目录
一、简介
1、什么是 MyBatis-Spring?
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession
并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException
。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
2、知识基础
在开始使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis 这两个框架和有关它们的术语。
MyBatis-Spring 需要以下版本:
MyBatis-Spring | MyBatis | Spring 框架 | Spring Batch | Java |
---|---|---|---|---|
2.0 | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
1.3 | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
二、快速入门
在 pom.xml 中导入依赖:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
要和 Spring 一起使用 MyBatis,需要在 Spring 应用上下文中定义至少两样东西:一个 SqlSessionFactory
和至少一个数据映射器类。
在 MyBatis-Spring 中,可使用 SqlSessionFactoryBean
来创建 SqlSessionFactory
。 只需要把下面代码放在 Spring 的 XML 配置文件中,这里需要一个DataSource(数据源):
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
</bean>
假如定义了一个如下的mapper接口:
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{userId}")
User getUser(@Param("userId") String userId);
}
可以通过MapperFactoryBean,把接口加入到Spring中:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
注意:所指定的映射器类必须是一个接口,而不是具体的实现类,上面例子用的是注解,也可以用xml配置的形式。
配置好之后,就可以像 Spring 中普通的 bean 注入方法那样直接注入映射器到 service 对象中。MapperFactoryBean 处理 SqlSession 的创建和关闭它。如果使用 了 Spring 的事务,那么当事务完成时,session 将会提交或回滚。最终,任何异常都会被翻 译成 Spring 的 DataAccessException 异常。
最后调用Mybatis数据方法只需一行代码:
public class UserServiceImpl implements UserService {
private UserMapper userMapper;
public void setUserMapper(UserMapper userMapper) {
this.userMapper = userMapper;
}
public User findUserById(String userId) {
return this.userMapper.getUser(userId);
}
MapperFactoryBean:这个类可以让你直接注入数据映射器接口到你的 service层bean 中。当使用映射器时,就像调用你的DAO一样调用它们就可以了。
三、整合实现①(SqlSessionTemplate)
SqlSessionTemplate 是 MyBatis-Spring 的核心。
它负责管理 MyBatis 的 SqlSession, 调用 MyBatis 的 SQL 方法, 翻译异常。 SqlSessionTemplate 是线程安全的, 可以被多个 DAO 所共享使用。它管理 session 的生命 周期,包含必要的关闭,提交或回滚操作。
SqlSessionTemplate 实现了 SqlSession 接口,在代码中无需对 MyBatis 的 SqlSession 替换。SqlSessionTemplate 通常是被用来替代默认的 MyBatis 实现的 DefaultSqlSession。
SqlSessionDaoSupport 需要一个 sqlSessionFactory 或 sqlSessionTemplate 属性来 设 置 。
1、引入Spring配置文件beans.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">
2、配置数据源替换mybaits的数据源
<!--配置数据源:数据源有非常多,可以使用第三方的,也可使使用Spring的-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
3、配置SqlSessionFactory,关联MyBatis
<!--配置SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--关联Mybatis-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="mapperLocations" value="classpath:com/jacko/dao/*.xml"/>
</bean>
4、注册sqlSessionTemplate,关联sqlSessionFactory
<!--注册sqlSessionTemplate , 关联sqlSessionFactory-->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<!--利用构造器注入-->
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>
5、增加Dao接口的实现类;私有化sqlSessionTemplate
public class UserDaoImpl implements UserMapper {
//sqlSession不用我们自己创建了,Spring来管理
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectUser() {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectUser();
}
}
6、注册bean实现
<bean id="userDao" class="com.jacko.dao.UserDaoImpl">
<property name="sqlSession" ref="sqlSession"/>
</bean>
7、测试
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper mapper = (UserMapper) context.getBean("userDao");
List<User> user = mapper.selectUser();
System.out.println(user);
}
结果成功输出!现在我们的Mybatis配置文件的状态!发现都可以被Spring整合
四、整合实现②(SqlSessionDaoSupport)
SqlSessionDaoSupport 是 一 个 抽象 的支 持 类, 用来 为你 提供 SqlSession,调用getSqlSession()方法你会得到一个 SqlSessionTemplate,之后可以用于执行 SQL 方法。
mybatis-spring1.2.3版以上才能使用此实现
dao继承Support类,直接利用getSqlSession()获得,然后直接注入SqlSessionFactory。比起第一种方式,此方式不需要管理SqlSessionTemplate,而且对事务的支持更加友好
1、将我们上面写的UserDaoImpl修改一下
public class UserDaoImpl extends SqlSessionDaoSupport implements UserMapper {
public List<User> selectUser() {
UserMapper mapper = getSqlSession().getMapper(UserMapper.class);
return mapper.selectUser();
}
}
2、修改bean的配置
<bean id="userDao" class="com.kuang.dao.UserDaoImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
3、测试
@Test
public void test2(){
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
UserMapper mapper = (UserMapper) context.getBean("userDao");
List<User> user = mapper.selectUser();
System.out.println(user);
}
五、事务
一个使用 MyBatis-Spring 的主要原因是它允许 MyBatis 参与到 Spring 的事务管理中。MyBatis-Spring 利用了存在于 Spring 中的 DataSourceTransactionManager。
配置了Spring的事务管理器之后,就可以在Spring中配置事务。并且支持@Transactional
注解和AOP风格的配置。在事务处理期间,一个单独的SqlSession
对象将会被创建和使用。当事务完成时,这个 session 会以合适的方式提交或回滚。
首先开启Spring事务处理功能,创建一个 DataSourceTransactionManager对象。
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
注意,:为事务管理器指定的 DataSource必须和用来创建 SqlSessionFactoryBean的是同一个数据源,否则事务管理器就无法工作了。
容器管理事务
如果你想让 Spring 参与到容器管理事务(CMT)中,那么 Spring 应该使用JtaTransactionManager 或它的容器指定的子类来配置
<tx:jta-transaction-manager />
如果你想使用CMT,而不想使用Spring的事务管理。必须配置SQLSessionFactory来使用MyBatis 的 ManagedTransactionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="transactionFactory">
<bean class="org.apache.ibatis.transaction.managed.ManagedTransactionFactory" />
</property>
</bean>
编程式事务管理
MyBatis 的 SqlSession
提供几个方法来在代码中处理事务。但是你不能在 Spring 管理的SqlSession
上调用SqlSession.commit()
,SqlSession.rollback()
或 SqlSession.close()
方法。如果这样做了,就会抛出 UnsupportedOperationException
异常。
如果你想编程式地控制事务,这段代码展示了使用 PlatformTransactionManager 来处理事务
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
TransactionStatus status = txManager.getTransaction(def);
try {
userMapper.insertUser(user);
}
catch (MyException ex) {
txManager.rollback(status);
throw ex;
}
txManager.commit(status);
六、使用SQLSession
在 MyBatis 中,你可以使用 SqlSessionFactory 来创建 SqlSession。一旦你获得一个 session 之后,你可以使用它来执行映射语句,提交或回滚连接,最后,当不再需要它的时 候, 你可以关闭 session。 使用 MyBatis-Spring 之后, 你不再需要直接使用 SqlSessionFactory 了,因为你的 bean 可以通过一个线程安全的 SqlSession 来注入,基于 Spring 的事务配置 来自动提交,回滚,关闭 session。