目前已经学习了 MyBatis 框架,Spring 框架,以及Spring MVC 框架。现阶段学习将这三个框架整合到一起,实现简单的前后端交互的曾删改差功能页面。
Mybatis 框架主要负责数据库的操作问题,以及数据回显。该框架将 SQL 与 Java 代码拆分开,降低耦合度的同时使代码可视程度更高,方便后期的 SQL 维护。
Spring 框架主要负责解决在企业级开发时业务逻辑层与其他层之间有大量耦合现象。将 Java 对象的创建和管理交给 Spring IOC 容器处理,减少了很多的对象重复创建,主要理念就是:谁用这个对象就由谁来创建!而不是事前创建完成再去调用!
Spring MVC 框架负责V-C交互的问题,即V(View:视图)和C(Controller:控制器)之间的交互问题,具体表现在:用户可以通过视图将请求数据提交给服务器端的控制器,而控制器可以接收到相关数据后进行处理,最终,给予客户端某个视图,使得客户端得到响应结果。
注:其实这些框架的出现就是为了实现一件事,代码解耦,优化程序!将原本写在一起的代码查分开来,各司其职,各自优化,使程序的开发过程更加简单,后续优化或者改动更加便捷,程序更加高效。
IDEA、MySql、Tomcat、Maven
数据库准备
创建数据库
CREATE DATABASE `ssmbuild`;
在 ssmbuild 库中创建相关的表并导入数据
-- 指定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,'从进门到进牢');
项目准备
创建基本的 maven 项目,并在 pom.xml 中导入相关依赖和姿态资源配置
依赖准备
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
<dependency>
<groupId>com.mchangegroupId>
<artifactId>c3p0artifactId>
<version>0.9.5.2version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.2version>
dependency>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.2version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.2version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-webmvcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>5.1.9.RELEASEversion>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.12version>
<scope>providedscope>
dependency>
dependencies>
静态资源配置
<build>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
build>
在 pojo 包下创建 Books 表的实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
创建 Mapper 接口,以及与接口对应的 xml
public interface BooksMapper {
// 查询全部书籍信息
List<Books> queryBooksAll();
// 根据书籍ID查询
List<Books> queryBooksId(@Param("bookID") int id);
// 新增书籍
int saveBooks(Books books);
// 修改书籍信息
int updateBooks(Books books);
// 删除书籍
int deleteBooks(Books books);
}
接口对应的 xml-BooksMapper.xml
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sys.mapper.BooksMapper">
<select id="queryBooksAll" resultType="com.sys.pojo.Books">
select * from books
select>
<select id="queryBooksId" resultType="com.sys.pojo.Books">
select * from books where 1=1
<if test="bookID != null">
and bookID = #{bookID}
if>
select>
<insert id="saveBooks" parameterType="com.sys.pojo.Books">
insert into books (bookName, bookCounts, detail)
values (#{bookName}, #{bookCounts}, #{detail})
insert>
<update id="updateBooks" parameterType="com.sys.pojo.Books">
update books set bookCounts = #{bookCounts} where 1=1
<if test="bookID != null">
and bookID = #{bookID}
if>
update>
<delete id="deleteBooks" parameterType="com.sys.pojo.Books">
delete from books where 1=1
<if test="booksID != null">
and booksID = #{booksID}
if>
delete>
mapper>
在resources 资源目录下创建资源配置文件
创建 MyBatis 配置文件:MyBatis-Config.xml
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.sys.pojo"/>
typeAliases>
<mappers>
<mapper resource="com/sys/dao/BooksMapper.xml"/>
mappers>
configuration>
创建数据源配置文件:database.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
在 service 包下创建接口
public interface BooksService {
// 查询全部书籍信息
List<Books> queryBooksAll();
// 根据ID查询
List<Books> queryBooksId();
// 新增书籍
int saveBooks(Books books);
// 修改书籍信息
int updateBooks(Books books);
// 删除书籍
int deleteBooks(Books books);
}
创建对应的实现类
@Service
public class BooksServiceImpl implements BooksService {
// 依赖注入,通过该 bean 调用 Mapper 接口的方法
@Autowired
BooksMapper bokksMapper;
public List<Books> queryBooksAll() {
List<Books> list = bokksMapper.queryBooksAll();
return list;
}
public List<Books> queryBooksId() {
List<Books> list = bokksMapper.queryBooksId(1);
return list;
}
public int saveBooks(Books books) {
Books book = new Books();
book.setBookName("Java 八股文,背!");
book.setBookCounts(5);
book.setDetail("从Java基础到框架的知识点,面试需要背");
return bokksMapper.saveBooks(book);
}
public int updateBooks(Books books) {
Books book = new Books();
book.setBookID(1);
book.setBookCounts(4);
return bokksMapper.updateBooks(books);
}
public int deleteBooks(Books books) {
Books book = new Books();
book.setBookID(3);
return bokksMapper.deleteBooks(books);
}
}
创建 Spring 配置文件:applicationContext.xml
<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>
配置 Spring 整合 dao层,创建 Spring-dao.xml
<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、导入数据源文件
<context:property-placeholder location="classpath:database.properties"/>
2、配置数据库连接池
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<property name="autoCommitOnClose" value="false"/>
<property name="checkoutTimeout" value="10000"/>
<property name="acquireRetryAttempts" value="2"/>
bean>
3、配置SqlSessionFactory对象
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
bean>
4、配置扫描Dao接口包,动态实现Dao接口注入到spring容器中
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.sys.dao"/>
bean>
文件完整配置
<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">
<context:property-placeholder location="classpath:database.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<property name="autoCommitOnClose" value="false"/>
<property name="checkoutTimeout" value="10000"/>
<property name="acquireRetryAttempts" value="2"/>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.sys.dao"/>
bean>
beans>
配置 Spring 整合 service 层,创建 Spring-Service.xml
<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、配置 service 包下的自动扫描
<context:component-scan base-package="com.sys.service"/>
2、将业务类注入到 Spring 容器中,由容器进行管理
<bean id="BooksServiceImpl" class="com.sys.service.impl.BooksServiceImpl">
<property name="booksMapper" ref="booksMapper"/>
bean>
3、配置事务管理器,管理注入进来的数据库连接池
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
文件完整配置
<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">
<context:component-scan base-package="com.sys.service"/>
<bean id="BooksServiceImpl" class="com.sys.service.impl.BooksServiceImpl">
<property name="booksMapper" ref="booksMapper"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
beans>
Spring 层配置完成:Spring 就是一个大杂烩,一个容器!这些配置都可以整合到 Spring 容器当中。
配置整合 Spring MVC 层
具体步骤如下:
配置 DispatcherServlet
<servlet>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
配置乱码过滤
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
filter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
配置 Session 过期时间
<session-config>
<session-timeout>15session-timeout>
session-config>
文件完整配置
<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>
<servlet-name>DispatcherServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:applicationContext.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>DispatcherServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>encodingFilterfilter-name>
<filter-class>
org.springframework.web.filter.CharacterEncodingFilter
filter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>utf-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
<session-config>
<session-timeout>15session-timeout>
session-config>
web-app>
创建 Spring-MVC.xml
<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>
配置SpringMVC 具体步骤如下
1、开启SpringMVC注解驱动
<mvc:annotation-driven/>
2、静态资源默认servlet配置
<mvc:default-servlet-handler/>
3、配置jsp 显示ViewResolver视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
bean>
4、扫描controller包下相关的bean
<context:component-scan base-package="com.sys.controller"/>
文件完整配置
<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"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
bean>
<context:component-scan base-package="com.sys.controller"/>
beans>
<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="Spring-Service.xml"/>
<import resource="Spring-dao.xml"/>
<import resource="Spring-MVC.xml"/>
beans>
编辑 controller 层代码,创建查询全部书籍信息的接口
@Controller
@RequestMapping("/book")
public class BooksController {
@Autowired
@Qualifier("BooksServiceImpl")//匹配 Spring 容器中具体的 Bean
BooksService booksService;
@RequestMapping("/queryBooks")
public String queryBooks(Model model){
// 调用 service
List<Books> list = booksService.queryBooksAll();
model.addAttribute("list",list);
// 调用 allBook.jsp
return "allBook";
}
}
编辑前端页面
优化首页 index.jsp(默认页面),使首页更好看那么一点点点
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<style>
a{
text-decoration: none;/* 超链接去掉下面的横线 */
color: aqua; /*修改超链接字体颜色*/
font-size: 10px; /*修改超链接字体大小*/
}
h3{
width:180px; /*宽*/
height:38px; /*高*/
margin: 100px auto; /*给文字上下左右添加 100 px 的扩展空间,不让文字贴在边框上*/
text-align: center; /*居中*/
line-height: 38px; /* 设置行高 */
background: cornsilk; /*设置颜色*/
border-radius: 5px; /*设置圆角边框*/
}
</style>
</head>
<body>
<h3>
<%--
${pageContext.request.contextPath}是JSP取得绝对路径的方法,等价于<%=request.getContextPath()%>
也就是:http://localhost:8080
最终拼接的 url 是:http://localhost:8080/book/queryBooks --%>
<a href="${pageContext.request.contextPath}/book/queryBooks">进入书籍展示页面</a>
</h3>
</body>
</html>
运行 http://localhost:8080
编辑 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</title>
<%-- BootStrap 美化界面 --%>
<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<style>
div {
/*垂直居中 */
vertical-align: middle;
/*水平居中*/
text-align: center;
}
</style>
</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 clearfix">
<div class="col-md-12 column">
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍详情</th>
</tr>
</thead>
<%--书籍信息从数据库中获取,在model中的list中遍历出来:forEach--%>
<tbody>
<%--获取 controller 中的 model 中的 addAttribute 方法存储进来的内容 注:此处的key必须和addAttribute方法的key保持一致,否则获取不到 --%>
<c:forEach var="book" items="${list}">
<tr>
<%--获取 book 对象中的详细信息--%>
<td>${book.bookID}</td>
<td>${book.bookName}</td>
<td>${book.bookCounts}</td>
<td>${book.detail}</td>
</tr>
</c:forEach>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
运行 http://localhost:8080/book/queryBooks,或者点击 index.jsp页面的按钮
SSM 框架整合都容易遇到的坑