SSM框架整合
SSM框架整合
将Spring + Spring MVC + MyBatis 整合到一个web应用中去
- Spring 负责对象管理(Ioc与AOP)
- Spring MVC 负责设计三层架构
- MyBatis 负责持久化操作 进行数据库操作
1、配置文件
0、准备环境
环境要求
- IDEA
- MySql 5.7
- Tomcat 9
- Maven 3.6
数据库环境
CREATE DATABASE `ssmbuild`;
USE `ssmbuild`;
DROP TABLE IF EXISTS `books`;
CREATE TABLE `books` (
`bookID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '书id',
`bookName` VARCHAR(100) NOT NULL COMMENT '书名',
`bookCounts` INT(11) NOT NULL COMMENT '数量',
`detail` VARCHAR(200) NOT NULL COMMENT '描述',
KEY `bookID` (`bookID`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`)VALUES
(1,'Java',1,'从入门到放弃'),
(2,'MySQL',10,'从删库到跑路'),
(3,'Linux',5,'从进门到进牢');
Mavne环境和静态资源导出配置
<dependencies>
<!--junit 单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>5.3.15</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.17</version>
</dependency>
<!--连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.9</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.17</version>
</dependency>
</dependencies>
静态资源导出配置
<build>
<resources>
<resource>
<directory>src/main/resources/</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
构建基本架构框架
-
dao : cn.mianju.mapper
-
pojo : cn.mianju.pojo
-
controller : cn.mianju.controller
-
service : cn.mianju.service
-
resources
-
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration>
-
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
-
1、MyBatis层配置
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=root
jdbc.password=123456
jdbc.url=jdbc:mysql://10.16.105.241:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=utf8
myBatis-config配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 设置别名 不需要输入全限定名-->
<typeAliases>
<package name="cn.mianju.pojo"/>
</typeAliases>
<!-- 千万要记住 这里不是类名 是路径名 分割是用/不是.!!!-->
<mappers>
<mapper resource="cn/mianju/mapper/BookMapper.xml"/>
</mappers>
</configuration>
在这个地方还遇到了一个坑 要注意
2、Spring层配置
spring-mapper.xml配置文件 整合Spring和Mybatis
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 关联数据库文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!-- druid连接池配置-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
</bean>
<!-- 配置Spring和MyBatis整合-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 自动配置mapper.xml-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="cn.mianju.mapper"/>
</bean>
</beans>
- 关联数据文件之后 在配置连接池的时候可以直接引用
- 连接池用的是alibaba的druid
- sqlSessionFactory是mybatis在spring中注册的工厂类 将数据源和config文件路径传入
- MapperScannerConfigurer 类可以自动配置Mapper的实现类 正常不用的话需要在mapper多建一个
spring-service.xml 配置文件 Spring整合service层
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描service包 -->
<context:component-scan base-package="cn.mianju.service"/>
<!-- 因为在spring-mapper.xml中配置了自动扫描包 这里可以直接调用到扫描到的bookMapper-->
<!-- 将BookServiceImpl注册到ioc容器中去-->
<bean id="bookService" class="cn.mianju.service.BookServiceImpl">
<property name="bookMapper" ref="bookMapper"/>
</bean>
<!-- 配置事务-->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
<!-- 注入数据库连接池-->
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
- 扫描service包那段代码 这个是使注解生效 但是我们没使用注解 可以不用这行代码
- 将这个service实现类注册到Spring IOC容器中 如果使用注解则不需要注册在配置文件 后期用getBean方法调用
- 事务管理器
3、SpringMVC层配置
spring-mvc.xml 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
">
<!-- 扫描包-->
<context:component-scan base-package="cn.mianju.controller"/>
<!-- 静态资源默认servlet-->
<mvc:default-servlet-handler/>
<!-- 开启mvc注解驱动-->
<mvc:annotation-driven/>
<!-- 视图解析器配置-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- 同之前 也是扫描注解 使注解生效
- 设置静态资源默认的servlet
- 开启mvc的注解驱动 不必再手动配置
- 视图解析器 如果制作API的话就不需要 返回json字符串 但是如果是页面需要从controller返回到视图解析器去寻找对应的页面资源
- viewClass 视图类 不能省略
- shuffix 前缀 会对返回的字符串进行拼接 然后去寻找对应的资源
- prefix 后缀 会对返回的字符串进行拼接 然后去寻找对应的资源
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--固定写法 将servlet交给SpringMVC来注入-->
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--启动顺序 越小越快 1就是和tomcat服务器一起启动-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--编码设置 预防乱码-->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--过滤器 url-pattern要 /* 否则不会过滤.jsp文件-->
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
- 将SpringMVC配置到web.xml中去 由SpringMVC来控制注册servlet
- 过滤器中 url-pattern 一定要是
/*
如果是 / 的话 是不会过滤jsp文件的 - CharacterEncodingFilter是Spring中的编码过滤器 大部分情况适用
4、配置文件汇总
现在所有的配置都配置好了 需要把它们关联汇总起来
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="classpath:spring/spring-mvc.xml"/>
<import resource="classpath:spring/spring-service.xml"/>
<import resource="classpath:spring/spring-mapper.xml"/>
</beans>
配置文件到这就结束
2、Mapper层
推荐由下到上的编写顺序 那么我们应该先去编写mapper层
BookMapper接口
BookMapper
package cn.mianju.mapper;
import cn.mianju.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookMapper {
List<Books> qureyAllBooks();
Books qureyBooksById(@Param("bookId") int id);
int modifyBooks(Books books);
int removeBooksById(@Param("bookId") int id);
List<Books> qureyBooksByName(@Param("bookName") String name);
int addBooks(Books books);
}
BookMapper实现
BookMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.mianju.mapper.BookMapper">
<insert id="addBooks" parameterType="Books">
insert into books (bookName, bookCounts, detail)
values (#{bookName}, #{bookCounts}, #{detail});
</insert>
<select id="qureyAllBooks" resultType="cn.mianju.pojo.Books">
select *
from books
</select>
<select id="qureyBooksById" parameterType="int" resultType="cn.mianju.pojo.Books">
select *
from books
where bookID = #{bookId}
</select>
<select id="qureyBooksByName" resultType="cn.mianju.pojo.Books">
select *
from books
where bookName like #{bookName};
</select>
<update id="modifyBooks" parameterType="Books">
update ssmbuild.books
set bookName = #{bookName},
bookCounts = #{bookCounts},
detail = #{detail}
where bookId = #{bookId};
</update>
<delete id="removeBooksById" parameterType="int">
delete
from books
where bookId = #{bookId};
</delete>
</mapper>
3、Pojo 层
pojo也就是实体类
映射数据库中的表
Books
Books
package cn.mianju.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookId;
private String bookName;
private int bookCounts;
private String detail;
}
4、Service层
service层和mapper层一样
需要编写一个接口类和一个实现类
BookService接口
BookService
package cn.mianju.service;
import cn.mianju.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookService {
List<Books> qureyAllBooks();
Books qureyBooksById(int id);
int modifyBooks(Books books);
int removeBooksById(int id);
List<Books> qureyBooksByName(String name);
int addBooks(Books books);
}
BookService实现
BookServiceImpl
package cn.mianju.service;
import cn.mianju.mapper.BookMapper;
import cn.mianju.pojo.Books;
import java.util.List;
//@Service
public class BookServiceImpl implements BookService{
// @Autowired
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
@Override
public List<Books> qureyAllBooks() {
return bookMapper.qureyAllBooks();
}
@Override
public Books qureyBooksById(int id) {
return bookMapper.qureyBooksById(id);
}
@Override
public int modifyBooks(Books books) {
return bookMapper.modifyBooks(books);
}
@Override
public int removeBooksById(int id) {
return bookMapper.removeBooksById(id);
}
@Override
public List<Books> qureyBooksByName(String name) {
return bookMapper.qureyBooksByName(name);
}
@Override
public int addBooks(Books books) {
return bookMapper.addBooks(books);
}
}
5、Controller层 和 视图层
这一块就是最终给用户的逻辑代码编写了
在Conntroller当前的功能中只有一个类 BookController
编写对应的方法
编写首页 index.jsp
index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE HTML>
<html>
<head>
<title>首页</title>
<style type="text/css">
a {
text-decoration: none;
color: black;
font-size: 18px;
}
h3 {
width: 180px;
height: 38px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background: deepskyblue;
border-radius: 4px;
}
</style>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/allbook">点击进入列表页</a>
</h3>
</body>
</html>
首先类需要注册到springIoc容器中
@Controller//使用注解将它注入到容器中
public class BookController {
@Autowired//自动装配属性
@Qualifier("bookService")//指定装配的Bean为bookService
private BookService bookService;
方法1 查询全部书籍
queryAllBooks
@Controller
public class BookController {
@Autowired
@Qualifier("bookService")
private BookService bookService;
/***
* 显示所有的图书
*
* @param model 转换成视图的模型
* @return 返回给视图解析器的URL 拼接后访问此资源
*/
@RequestMapping("/allbook")
public String qureyAllBooks(Model model) {
List<Books> books = bookService.qureyAllBooks();
model.addAttribute("list", books);
return "allbook";
}
}
对应的 allbook.jsp
allbook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍列表</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>书籍列表 —— 显示所有书籍</small>
</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/toaddbook">新增</a>
</div>
<div class="col-md-4 column"></div>
<div class="col-md-4 column">
<form action="${pageContext.request.contextPath}/querybook" class="form-inline" style="float: right">
<input type="text" name="bookname" class="form-control" placeholder="请输入要查询的书名">
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名字</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="book" items="${requestScope.get('list')}">
<tr>
<td>${book.getBookId()}</td>
<td>${book.getBookName()}</td>
<td>${book.getBookCounts()}</td>
<td>${book.getDetail()}</td>
<td>
<a href="${pageContext.request.contextPath}/tomodiybook?id=${book.getBookId()}">更改</a>
|
<a href="${pageContext.request.contextPath}/removebook/${book.getBookId()}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
- 需要导入包 taglib
- 循环
${requestScope.get('list')}
这个是由后端的setAttribute
方法传过来的model.addAttribute("list", books);
在jsp中循环的变量就是list
${pageContext.request.contextPath}
jsp的内置对象 获取到当前的根路径
方法2 添加书籍
addBook
/***
* 跳转至添加书籍页面
* @return 返回的是提交的接口的路径
*/
@RequestMapping("/toaddbook")
public String addBooks() {
return "addbook";
}
/***
* 提交添加书籍的接口
* @param book 要添加的数据
* @return 重定向至全部书籍处
*/
@RequestMapping("/addbook")
public String addPage(Books book) {
bookService.addBooks(book);
return "redirect:/allbook";
}
- 首先建立一个供用户添加书籍的网页界面
- 当用户点击 提交/添加 时就去调用下方的接口 接口中实现添加书籍
- 最后重定向至 查询所有书籍 页面
addbook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>新增书籍</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>新增书籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/addbook" method="post">
书籍名称:<input type="text" name="bookName"><br><br><br>
书籍数量:<input type="text" name="bookCounts"><br><br><br>
书籍详情:<input type="text" name="detail"><br><br><br>
<input type="submit" value="添加">
</form>
</div>
- 以Post方式传到 localhost/addbook 这个页面下
- bookName、bookCounts、detail 会根据Books实体类的对应的属性转换为Books
- 所以
public String addPage(Books book)
传入参数为Books并没有问题
- 所以
方法3 修改书籍
modiyBook
/***
* 修改书籍的页面 由书籍侧边的修改进入
* @param model 添加添加这个books是给前端遍历获取到这个属性 一定要和前端引用属性名对应!
* @param id 前端遍历每个书籍侧边的修改,对应的id
* @return 提交修改的接口路径
*/
@RequestMapping("/tomodiybook")
public String modiyBook(Model model, int id) {
System.out.println(id);
Books books = bookService.qureyBooksById(id);
model.addAttribute("books", books);
return "modiybook";
}
/***
* 实施修改书籍的接口
* @param book 这个books是前端点击提交后 传入的属性 但是ID不会变 所以根据ID修改就行了
* @return 重定向到所有书籍
*/
@RequestMapping("/modiybook")
public String modiyBookPage(Books book) {
System.out.println(book);
System.out.println("=====================");
bookService.modifyBooks(book);
Books books = bookService.qureyBooksById(book.getBookId());
System.out.println(books);
return "redirect:/allbook";
}
- 根据书籍 id 先获取到这个书籍 然后
addAttribute("books", books)
前端显示出来原来信息 id由前端(路径)传入 - 提交后跳转至 modiybook 接口 也是post传入对应的属性然后修改成传入的book
- 然后再重定向跳转至 显示所有书籍 页面
modiybook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改信息</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>修改信息</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/modiybook" method="post">
<input type="hidden" name="bookId" value="${books.getBookId()}"/>
书籍名称:<input type="text" name="bookName" value="${books.getBookName()}"/>
书籍数量:<input type="text" name="bookCounts" value="${books.getBookCounts()}"/>
书籍详情:<input type="text" name="detail" value="${books.getDetail() }"/>
<input type="submit" value="提交"/>
</form>
</div>
方法4 删除书籍
删除书籍就简单多了 不需要再写页面(当然你想有个确定框也可以)
removeBook
/***
* 直接删除书籍的接口
* Restful 风格
* @param id 根据ID来删除书籍
* @return 重定向至全部书籍处
*/
@RequestMapping("/removebook/{bookId}")
public String removeBook(@PathVariable("bookId") int id) {
bookService.removeBooksById(id);
return "redirect:/allbook";
}
- 此处使用的是 Restful 风格的链接形式
- 在
@RequestMapping("/removebook/{bookId}}")
中引用变量id的话需要加上注解且大括号中引用
- 在
- 删除后重定向回到 显示所有书籍
方法5 搜索书籍
搜索书籍的话使用的是mysql 中的 like 来查询对应的书籍
qureyBookByName
/***
* 根据名称搜索书籍
* @param model 查询结果返回至视图
* @param bookname 传入的书籍名称
* @return 返回查询页面
*/
@RequestMapping("/querybook")
public String qureyBookByName(Model model,String bookname) {
System.out.println(bookname);
bookname = "%" + bookname + "%";
List<Books> books = bookService.qureyBooksByName(bookname);
model.addAttribute("list",books);
//return "/allbook";
return "/querybook";
}
jsp的话 是使用和allbook.jsp一样的 也可以直接返回allbook.jsp 只要保证 model.addAttribute("list",books);
中的list和jsp中的遍历的参数名一样就可以了
querybook.jsp
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍列表</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 引入 Bootstrap -->
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<div class="page-header">
<h1>
<small>书籍列表 —— 显示所有书籍</small>
</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4 column">
<a class="btn btn-primary" href="${pageContext.request.contextPath}/toaddbook">新增</a>
</div>
<div class="col-md-4 column"></div>
<div class="col-md-4 column">
<form action="" class="form-inline" style="float: right">
<input type="text" name="bookname" class="form-control" placeholder="请输入要查询的书名">
<input type="submit" value="查询" class="btn btn-primary">
</form>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名字</th>
<th>书籍数量</th>
<th>书籍详情</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="book" items="${requestScope.get('list')}">
<tr>
<td>${book.getBookId()}</td>
<td>${book.getBookName()}</td>
<td>${book.getBookCounts()}</td>
<td>${book.getDetail()}</td>
<td>
<a href="${pageContext.request.contextPath}/tomodiybook?id=${book.getBookId()}">更改</a>
|
<a href="${pageContext.request.contextPath}/removebook/${book.getBookId()}">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
6、配置Tomcat 运行程序
到这里就是完成了整个的项目
可以配置tomcat进行运行测试
整个项目结构:
7、遇到的坑
在这次SSM项目整合过程中呢也是遇到了很多坑 在这里总结一下
-
mybatis-config.xml 配置文件中的
<mapper resource="cn/mianju/mapper/BookMapper.xml"/>
我打成了包路径- 也就是
<mapper resource="cn.mianju.mapper.BookMapper"/>
(被自己蠢哭😭) 导致BookService一直创建不出来
- 也就是
-
视图解析器 拼接找不到jsp资源 这个就很简单 报错就看的出来 我之前是把前后缀写反了 导致拼接出来的是个鬼都看不懂的玩意
-
<property name="prefix" value="/WEB-INF/jsp/"/><!--前缀--> <property name="suffix" value=".jsp"/><!--后缀-->
-
-
Mapper层查询的返回值 增删改返回值为 int 类型 而 查返回值才为 实体类
-
(这个应该不是坑)在 spring-service.xml 中注册了 bookService 的bean 但是那个地方开启的注解扫描
- 也就是可以在 BookServiceImpl 类中使用注解就不需要在配置文件中去配置了 (除了MVC还是使用配置文件比较好)
- 别问 问就是 乌龟的屁股 (龟腚)
-
还有就是!静态导出的问题!!!maven是一个 约定大于配置 的插件 由于我们的BookMapper.xml是写在
cn.mianju.mapper
包下的 我给忘记了 所以有的时候还是看看out目录下的classes文件夹下有没有对应的文件- 默认是不导出xml、properties文件的 这个时候去maven中配置一下
<build>
(文档上方有)就可以了
- 默认是不导出xml、properties文件的 这个时候去maven中配置一下
-
还有最无语的!!!他妈的编码问题 我找了半天都是提示
MalformedByteSequenceException: 1 字节的 UTF-8 序列的字节 1 无效。
最后是发现编码问题-
把缓存全部清除 缓存全部清除 缓存全部清除后 pom.xml 中
<properties>
标签中的内容改为 -
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties>
-
然后打开设置
settings > Editor > File Encodings
找到Project Encoding:
修改为UTF-8 -
属实是给我整无语了
-
-
如果Mybatis输入的sql查询不到数据的话 试着把
#{}
改为${}
-
查询到了数据但是返回值中还是为null的话 就需要到mybatis-config.xml中把自动映射属性打开
-
<settings> <!--开启自动映射数据和实体类的属性--> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
-
注意这里自动映射的话是需要驼峰命名法的
-
-
22年4月18号 我破防了 我用maven构建一个项目然后框架全部搭好后 去controller进行测试 但是怎么都不能进入controller
- 从一开始以为的配置文件出错 疯狂检查 发现没有问题 ,然后以为导包问题, 也查看了没有问题 maven也配置了静态资源过滤问题(虽然根本用不到)
- 最后发现没有target文件夹!!! 而且out文件夹下 只有mapper的xml文件 合着类是一个没导出来啊?!
- 验证我的猜想 我去test底下建立一个Test 类 然后psvm进行测试 发现 !!“找不到主类”
- 最后怎么都解决不了 重新构建一个项目 把这个项目中的文件移植到那边后 可以运行 😅 叔叔我啊 是真的想打人了
- 应该是maven构建的一个问题(或者是IDEA的?)最后重新构建一个项目就可以使用了
-
在项目过程中 我们会可能会用到不只一个 properties 配置文件 而我们在 spring-mapper.xml 中 配置了以后 再去配置的话就会不会引用到后面的配置文件 这个时候就是重复引用了
- 重复引用的话 需要在每一个
<context:property-placeholder>
中 添加ignore-unresolvable="true"
属性 <context:property-placeholder location="yyy.properties" ignore-unresolvable="true"/>
- 重复引用的话 需要在每一个