整合 SSM 的核心在配置文件。
1、环境搭建1.1、数据库
book 表
主键自增,插入数据时无需手动设置。
CREATE TABLE `mybatis`.`book`(
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'ID',
`name` VARCHAR(100) NOT NULL COMMENT '书名',
`count` INT(10) NOT NULL COMMENT '数量',
PRIMARY KEY (`id`)
) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
1.2、项目搭建
新建 Maven 项目,添加 web 框架支持。
导入依赖
导入依赖,并在项目结构中手动添加 lib 目录。
-
MyBatis
- MyBatis 框架:mybatis
- 数据库连接:mysql-connector-java
- C3P0 连接池:c3p0
-
Spring
- Spring 框架:spring-webmvc
- AOP:aspectjweaver
- 整合
- 整合框架:mybatis-spring
- Spring 获取数据源:spring-jdbc
- Servlet、JSP、JSTL
- JUnit
<dependencies>
<!-- MyBatis框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!-- 数据库连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
<!-- C3P0连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.5.5</version>
</dependency>
<!-- Spring框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<!-- AOP -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7</version>
</dependency>
<!-- 整合框架 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!-- Spring获取数据源-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
<!--Servlet、JSP、JSTL-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- JUnit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
项目包结构
- pojo / entity / ...
- dao / mapper
- service
- controller
实体类
Book
注意: ORM 原则
/**
* ID
*/
private int id;
/**
* 书名
*/
private String name;
/**
* 数量
*/
private int count;
DAO层
BookMapper
注意:Java 也有 Book 类,不要导错包。
public interface BookMapper {
/**
* 增加一本书
*
* @param book 待添加的书
* @return 受影响行数
*/
int insertBook(Book book);
/**
* 通过ID删除一本书
*
* @param id 待删除书ID
* @return 受影响行数
*/
int deleteBook(int id);
/**
* 更新一本书
*
* @param book 新书
* @return 受影响行数
*/
int updateBook(Book book);
/**
* 通过ID查找书
* @param id 待查找书ID
* @return 待查找书
*/
Book getBook(int id);
/**
* 查找所有书
* @return 书的列表
*/
List<Book> listBooks();
}
Service层
BookService
public interface BookService {
/**
* 增加一本书
*
* @param book 待添加的书
* @return 受影响行数
*/
int insertBook(Book book);
/**
* 通过ID删除一本书
*
* @param id 待删除书ID
* @return 受影响行数
*/
int deleteBook(int id);
/**
* 更新一本书
*
* @param book 新书
* @return 受影响行数
*/
int updateBook(Book book);
/**
* 通过ID查找书
* @param id 待查找书ID
* @return 待查找书
*/
Book getBook(int id);
/**
* 查找所有书
* @return 书的列表
*/
List<Book> listBooks();
}
BookServiceImpl
- Service 层调用 DAO 层方法;
- 提供 BookMapper 接口,用于 Spring 依赖注入。
public class BookServiceImpl implements BookService{
/**
* Service层调用DAO层
*/
private BookMapper bookMapper;
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
@Override
public int insertBook(Book book) {
return bookMapper.insertBook(book);
}
@Override
public int deleteBook(int id) {
return bookMapper.deleteBook(id);
}
@Override
public int updateBook(Book book) {
return bookMapper.updateBook(book);
}
@Override
public Book getBook(int id) {
return bookMapper.getBook(id);
}
@Override
public List<Book> listBooks() {
return bookMapper.listBooks();
}
}
2、配置文件
-
MyBatis
- BookMapper.xml
- db.properties
- mybatis-config.xml
-
Spring
- spring-mybatis.xml
- spring-service.xml
-
SpringMVC
- web.xml
- spring-mvc.xml
- applicationContext.xml
| 配置文件 | 作用 | 说明 |
|---|---|---|
| BookMapper.xml | 编写 SQL 语句 | DAO 层的 Mapper 对应的 XML |
| db.properties | 数据库连接信息 | (非必要)不创建 properties 文件也可 即可以直接将连接信息写入配置文件中 |
| mybatis-config.xml | 配置 MyBatis | (非必要)框架整合后 MyBatis 的工作交给 Spring 完成 |
| spring-mybatis.xml | 完成 MyBatis 的工作 | 数据源、sqlSessionFactory、Mapper 扫描配置器(或SqlSessionTemplate) |
| spring-service | 管理 Service 层 | 添加注解支持、注册 Bean、声明式事务、AOP 等 |
| web.xml | 注册 DispatcherServlet、过滤乱码 | |
| spring-mvc | 管理 Controller 层 | 添加注解支持、过滤静态资源、注解驱动、视图解析器 |
| applicationContext.xml | 合并 Spring 配置文件 | spring-mybatis.xml、spring-service.xml、spring-mvc.xml |
2.1、MyBatis
Mapper.xml
BookMapper.xml
对应 DAO 层的 Mapper,用于编写 SQL 语句。
注意:select 语句要有 resultType 或 resultMap 结果集映射。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="indi.jaywee.mapper.BookMapper">
<insert id="insertBook">
insert into mybatis.book(name, count)
values (#{name}, #{count})
</insert>
<delete id="deleteBook">
delete
from mybatis.book
where id = #{id}
</delete>
<update id="updateBook">
update mybatis.book
set name = #{name},
count=#{count}
where id = #{id}
</update>
<select id="getBook" parameterType="_int" resultType="book">
select *
from mybatis.book
where id = #{id};
</select>
<select id="listBooks" resultType="book">
select *
from mybatis.book
</select>
</mapper>
数据库连接文件
db.properties
这个文件是非必要的,其中的配置信息可以直接写在配置文件中。
写成 properties 文件是为了方便修改。
注意:必须有jdbc.的前缀,否则报错。
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=529118
MyBatis 配置文件
mybatis-config.xml
这个文件是非必要的,因为 MyBatis 的工作可以交给 Spring 完成。
- 也就是说,可以去掉这个配置文件,直接在 spring-mybatis 中配置;
- 保留这个文件,可以专门用于配置别名(typeAlias)、设置(settings)。
<?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="indi.jaywee.pojo"/>
</typeAliases>
<!-- 设置 -->
</configuration>
2.2、Spring:DAO层(MyBatis)
spring-mybatis.xml
用于完成 MyBatis 的工作。
-
数据源
- 引入数据库配置文件(非必要):如果没有写 db.properties,可以省去该步骤;
- C3P0 连接池:可以使用其他连接池,或者用 Spring 自带的数据源;
-
sqlSessionFactory
- 绑定数据源
- 绑定 MyBatis 配置文件(非必要):因为 Spring 可以完成 MyBatis 的所有工作。
- 注册 Mapper
-
Mapper 扫描配置器
将 Mapper 自动注入容器,省去创建 MapperImpl 的操作。
- 指定要扫描的包;
- 为 Mapper 接口注入 sqlSessionFactory。
【如果没有这个配置,我们需要创建一个 Mapper 实现类,详见 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="db.properties"/>
<!-- C3P0连接池 -->
<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}"/>
<!-- C3P0连接池的私有属性 -->
<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>
<!-- sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 绑定数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 绑定MyBatis配置文件 -->
<property name="configLocation" value="mybatis-config.xml"/>
<!-- 注册Mapper-->
<property name="mapperLocations" value="indi/jaywee/mapper/*.xml"/>
</bean>
<!-- 将Mapper自动注入容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定要扫描的包 -->
<property name="basePackage" value="indi.jaywee.mapper"/>
<!-- 注入sqlSessionFactory -->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
</beans>
2.3、Spring:Service层
spring-service.xml
使用 Spring 管理 Service 层。
-
添加注解支持:扫描指定包下的 Bean ,被扫描的 Bean 中包含的类级别的注解才会生效,Bean 才会被注册到容器中;
-
注册 Bean:注入依赖;
-
声明式事务;
-
AOP 等等。
<?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">
<!-- 注册DispatcherServlet -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 绑定配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!-- 启动优先级 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</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>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.4、SpringMVC:Controller层
web.xml
- 注册 DispatcherServlet
- 绑定配置文件;
- 启动优先级;
- 过滤乱码
<?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"
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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描包 -->
<context:component-scan base-package="indi.jaywee.controller"/>
<!-- 过滤静态资源 -->
<mvc:default-servlet-handler/>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
springmvc-servlet.xml
- 添加注解支持:扫描指定包下的 Bean ,被扫描的 Bean 中包含的类级别的注解才会生效,Bean 才会被注册到容器中;
- 过滤静态资源:如 CSS、JS、HTML、MP3、MP4...
-
注解驱动:在 Spring 中一般使用 @RequestMapping 注解来处理映射关系,使用该注解需要注册
处理器映射和处理器适配器,annotation-driven 自动注入以上两个实例; - 内部资源视图解析器
<?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"
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
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 扫描包 -->
<context:component-scan base-package="indi.jaywee.controller"/>
<!-- 过滤静态资源 -->
<mvc:default-servlet-handler/>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!-- 后缀 -->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
2.5、applicationContext
将 Spring 配置文件合并为一个文件。
- spring-mybatis
- spring-service
- spring-mvc
<?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="spring-mybatis.xml"/>
<import resource="spring-service.xml"/>
<import resource="spring-mvc.xml"/>
</beans>
到此,SSM基础框架搭建完成。
3、测试public class BookMapperTest {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = context.getBean("bookService", BookService.class);
@Test
public void testInsertBook() {
Book book = new Book();
book.setName("Initial D");
book.setCount(10);
int i = bookService.insertBook(book);
if (i > 0) {
System.out.println("添加" + i + "本书");
}
}
@Test
public void testDeleteBook() {
int i = bookService.deleteBook(2);
if (i > 0) {
System.out.println("删除" + i + "本书");
}
}
@Test
public void testUpdateBook() {
Book book = new Book(1, "Jaywee Life", 9);
int i = bookService.updateBook(book);
if (i > 0) {
System.out.println("更新" + i + "本书");
}
}
@Test
public void testGetBook() {
Book book = bookService.getBook(1);
System.out.println(book);
}
@Test
public void testListBooks() {
List<Book> books = bookService.listBooks();
for (Book book : books) {
System.out.println(book);
}
}
}
















