第10章 MyBatis与Spring的整合
学习目标
● 掌握传统DAO方式的开发整合
● 掌握Mapper接口方式的开发整合
10.1 整合环境搭建
10.1.1 准备所需JAR包
1.Spring框架所需的JAR包
Spring框架所需要准备的JAR包共10个,其中包括:4个核心模块JAR, AOP开发使用的JAR, JDBC和事务的JAR(其中核心容器依赖的commons-logging的JAR在MyBatis框架的lib包中已经包含,所以这里不必再加入)
· aopalliance-1.0.jar
· aspectjweaver-1.8.10.jar
· spring-aop-4.3.6.RELEASE.jar
· spring-aspects-4.3.6.RELEASE.jar
· spring-beans-4.3.6.RELEASE.jar
· spring-context-4.3.6.RELEASE.jar
· spring-core-4.3.6.RELEASE.jar
· spring-expression-4.3.6.RELEASE.jar
· spring-jdbc-4.3.6.RELEASE.jar
· spring-tx-4.3.6.RELEASE.jar
2.MyBatis框架所需的JAR包
MyBatis框架所需要准备的JAR包共13个,其中包括:核心包mybatis-3.4.2.jar以及其解压文件夹中lib目录中的所有JAR
· ant-1.9.6.jar
· ant-launcher-1.9.6.jar
· asm-5.1.jar
· cglib-3.2.4.jar
· commons-logging-1.2.jar
· javassist-3.21.0-GA.jar
· log4j-1.2.17.jar· log4j-api-2.3.jar
· log4j-core-2.3.jar· mybatis-3.4.2.jar
· ognl-3.1.12.jar· slf4j-api-1.7.22.jar
· slf4j-log4j12-1.7.22.jar
3.MyBatis与Spring整合的中间JAR
MyBatis社区自己开发了一个用于整合这两个框架的中间件——MyBatis-Spring。
4.数据库驱动JAR包
mysql-connector-java-5.1.40-bin.jar
5.数据源所需JAR包
DBCP数据源,所以需要准备DBCP和连接池的JAR包
· commons-dbcp2-2.1.1.jar
· commons-pool2-2.4.2.jar
10.1.2 编写配置文件
db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/mybatis?characterEncoding=utf8&useSSL=false&serverTimezone=UTC
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
最大连接数(maxTotal)、最大空闲连接数(maxIdle)以及初始化连接数(initialSize)
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"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<!-- 配置数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="maxTotal" value="${jdbc.maxTotal}"/>
<property name="maxIdle" value="${jdbc.maxIdle}"/>
<property name="initialSize" value="${jdbc.initialSize}"/>
</bean>
<!-- 事务管理器 依赖于数据源-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--注册事务管理器驱动-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- 配置Mybatis工厂-->
MyBatis工厂的作用就是构建SqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 注入核心配置文件位置-->
<property name="configLocation" value="classpath:mybatis-config3.xml"/>
提供数据源和MyBatis配置文件路径后,Spring的IoC容器就会在初始化id为sqlSessionFactory的Bean时解析MyBatis的配置文件,并与数据源一同保存到Spring的Bean中
</bean>
</beans>
问题:applicaionContext.xml文件中,配置数据源时使用${jdbc.url}取不到配置文件db.properies里的值
原因:不详
解决方法:在db.properies回车一下,代码颜色变色即解决
在mybatis-config.xml中配置驱动name="driver"
在applicaionContext.xml中配置驱动name="driverClassName"
mapper-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>
<!-- 配置别名-->
<typeAliases>
<package name="com.itheima.po"/>
</typeAliases>
<!-- 配置Mapper的位置-->
<mappers>
……
</mappers>
</configuration>
10.2 传统DAO方式的开发整合
需要编写DAO接口以及接口的实现类,并且需要向DAO实现类中注入SqlSessionFactory,然后在方法体内通过SqlSessionFactory创建SqlSession
可以使用mybatis-spring包中所提供的SqlSessionTemplate类或SqlSessionDaoSupport类来实现此功能
· SqlSessionTemplate:核心类
(1)负责管理MyBatis的SqlSession的生命周期,包含必要的关闭、提交和回滚操作
(2)调用MyBatis的SQL方法,保证使用的SqlSession和当前Spring的事务是相关的。
· SqlSessionDaoSupport:抽象支持类
继承了DaoSupport类,作为DAO的基类,getSqlSession()方法可获取所需的SqlSession。
1.持久层
(1)持久化类

getter/setter/toString
(2)mapper文件
<mapper namespace="com.itheima.mapper.CustomerMapper1">
<!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer"
resultType="com.itheima.po.Customer1">
select * from t_customer where id = #{id}
</select>
</mapper>
(3)mybatis文件
<mappers>
<mapper resource="com/itheima/mapper/CustomerMapper1.xml"/>
</mappers>
2.DAO层
(1)dao
public interface CustomerDao {
public Customer1 findCustomerById(Integer id);
}
(2)daoImpl
public class CustomerDaoImpl extends SqlSessionDaoSupport implements CustomerDao {
@Override
public Customer1 findCustomerById(Integer id) {
return this.getSqlSession().selectOne("com.itheima.mapper.CustomerMapper1.findCustomerById",id);
}
}
(3)applicationContext.xml中实例化impl
<!-- 实例化Dao-->
<bean id="customerDao" class="com.itheima.dao.impl.CustomerDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
3.整合测试
public class DaoTest {
@Test
public void findCustomerByIdDaoTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext7.xml");
CustomerDao customerDao = (CustomerDao) applicationContext.getBean("customerDao");
System.out.println(customerDao.findCustomerById(1));
}
}
根据类的类型来获取Bean
CustomerDao customerDao = act.getBean(CustomerDao.class);
10.3 Mapper接口方式的开发整合
DAO开发方式会出现大量的重复代码,在方法中也需要指定映射文件中执行语句的id,并且不能保证编写时id的正确性(运行时才能知道)
10.3.1 基于MapperFactoryBean的整合
MyBatis-Spring团队提供的一个用于根据Mapper接口生成Mapper对象的类
· mapperInterface:用于指定接口。
· SqlSessionFactory:用于指定SqlSessionFactory。
· SqlSessionTemplate:用于指定SqlSessionTemplate。如果与SqlSessionFactory同时设定,则只会启用SqlSessionTemplate。
1. CustomerMapper.java
public interface CustomerMapper2 {
public Customer1 findCustomerById(Integer id);
}
CustomerMapper.xml
<mapper namespace="com.itheima.mapper.CustomerMapper2">
<!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer"
resultType="com.itheima.po.Customer1">
select * from t_customer where id = #{id}
</select>
</mapper>
CustomerMapper.java和CusotmerDao接口基本相同,区别在于,本案例将接口文件改名并与映射文件一起放在了com.itheima.mapper包中。
2.MyBatis-config
<mappers>
<mapper resource="com/itheima/mapper/CustomerMapper2.xml"/>
</mappers>
如果完全遵循了编写规范,那么在配置文件中可以不引入映射文件。
3.applicationContext.xml
<!-- Mapper代理开发-->
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.itheima.mapper.CustomerMapper2"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
4.测试类
@Test
public void findCustomerByIdMapperTest(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext7.xml");
CustomerMapper2 customerMapper2 = (CustomerMapper2) applicationContext.getBean(CustomerMapper2.class);
System.out.println(customerMapper2.findCustomerById(1));
}
Mapper接口编程方式只需要程序员编写Mapper接口(相当于DAO接口)
规范:
(1)Mapper接口的名称和对应的Mapper.xml映射文件的名称必须一致。
(2)Mapper.xml文件中的namespace与Mapper接口的类路径相同(即接口文件和映射文件需要放在同一个包中)。(3)Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同。
(4)Mapper接口中方法的输入参数类型要和Mapper.xml中定义的每个sql的parameterType的类型相同。
(5)Mapper接口方法的输出参数类型要和Mapper.xml中定义的每个sql的resultType的类型相同。
只要遵循了这些开发规范,MyBatis就可以自动生成Mapper接口实现类的代理对象,从而简化我们的开发。
10.3.2 基于MapperScannerConfigurer的整合
MyBatis-Spring团队提供了一种自动扫描的形式来配置MyBatis中的映射器——采用MapperScannerConfigurer类。
· basePackage:指定映射接口文件所在的包路径,当需要扫描多个包时可以使用分号或逗号作为分隔符。指定包路径后,会扫描该包及其子包中的所有文件。
· annotationClass:指定了要扫描的注解名称,只有被注解标识的类才会被配置为映射器。
· sqlSessionFactoryBeanName:指定在Spring中定义的SqlSessionFactory的Bean名称。
· sqlSessionTemplateBeanName:指定在Spring中定义的SqlSessionTemplate的Bean名称。如果定义此属性,则sqlSessionFactoryBeanName将不起作用。
· markerInterface:指定创建映射器的接口。
<!-- Mapper代理开发(基于MapperScannerConfigurer)-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper" />
</bean>
配置后无需在mybatis-config下配置mapper文件的位置、无需在spring的配置文件中单独配置mapper的bean
10.4 测试事务
在MyBatis+Spring的项目中,事务是由Spring来管理的。
在项目中,业务层(Service层)既是处理业务的地方,又是管理数据库事务的地方。要对事务进行测试,首先需要创建业务层,并在业务层编写添加客户操作的代码;然后在添加操作的代码后,有意地添加一段异常代码(如int i = 1/0;)来模拟现实中的意外情况;最后编写测试方法,调用业务层的添加方法。这样,程序在执行到错误代码时就会出现异常。在没有事务管理的情况下,即使出现了异常,数据也会被存储到数据表中;如果添加了事务管理,并且事务管理的配置正确,那么在执行上述操作时,所添加的数据将不能够插入到数据表中。
1.customerMapper.java
public void addCustomer(Customer1 customer1);
2.CustomerService
public interface CustomerService {
public void addCustomer(Customer1 customer1);
}
3.CustomerServiceImpl
@Service
//@Transactional
public class CustomerServiceImpl implements CustomerService {
// 注解注入CustomerMapper
@Autowired
private CustomerMapper2 customerMapper2;
@Override
public void addCustomer(Customer1 customer1) {
this.customerMapper2.addCustomer(customer1);
int i = 1 / 0 ;
}
}
4.applicationContext.xml
<context:component-scan base-package="com.itheima.service"/>
5.测试类
public class TransactionTest {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext7.xml");
CustomerService customerService = applicationContext.getBean(CustomerService.class);
Customer1 customer1 = new Customer1();
customer1.setUsername("zhangs88a");
customer1.setJobs("manager");
customer1.setPhone("123131545");
customerService.addCustomer(customer1);
}
}
【思考题】
1.请简述MyBatis与Spring整合所需JAR包的种类。
Spring核心包core、beans、expression还有一个,事务管理tx,jdbc
Mybatis核心包
spring-mybatis核心包
数据源
2.请简述MapperFactoryBean和MapperScannerConfigurer的作用。
前者生成mapper,后者扫描mapper配置文件?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?