首先对于 Mybatis 的主配置文件, 只需要修改一处地方, 将事务交给 Spring 管理, 其它地方可以原封不动.
<?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>
- <properties resource="jdbc.properties"></properties>
- <typeAliases>
- <package name="com.sunwii.mybatis.bean" />
- </typeAliases>
- <environments default="development">
- <environment id="development">
- <!-- 将事务交张 Spring 管理 -->
- <transactionManager type="org.mybatis.spring.transaction.SpringManagedTransactionFactory" />
- <dataSource type="POOLED">
- <property name="driver" value="${driver}" />
- <property name="url" value="${url}" />
- <property name="username" value="${user}" />
- <property name="password" value="${password}" />
- </dataSource>
- </environment>
- </environments>
- <!-- 这里 mappers 块可以保留或删除或配置不存在的包也无所谓 -->
- <mappers>
- <package name="Xcom/sunwii/mybatis/mapper"></package>
- </mappers>
- </configuration>
然后修改一下 Mybatis 工具类, 重新命令为 SqlSessionFactoryBuilder:
- public class SessionFactoryBuilder {
- private String mybatisConfigPath;
- public String getMybatisConfigPath() {
- return mybatisConfigPath;
- }
- public void setMybatisConfigPath(String mybatisConfigPath) {
- this.mybatisConfigPath = mybatisConfigPath;
- }
- public SqlSessionFactory createSqlSessionFactory() {
- SqlSessionFactory factory = null;
- InputStream inputStream;
- try {
- inputStream = Resources.getResourceAsStream(this.mybatisConfigPath);
- factory = new SqlSessionFactoryBuilder().build(inputStream);
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return factory;
- }
- }
Spring 的配置文件也就比较简洁:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:p="http://www.springframework.org/schema/p"
- xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:tx="http://www.springframework.org/schema/tx"
- 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-4.0.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">
- <!-- 动态工厂实例化一个 SqlSessionFactory -->
- <bean id="sessionFactoryBuilder" class="com.sunwii.mybatis.util.SessionFactoryBuilder">
- <property name="mybatisConfigPath" value="mybatis-config.xml" />
- </bean>
- <bean id="sessionFactory" factory-bean="sessionFactoryBuilder" factory-method="createSqlSessionFactory" />
- <!-- Mapper 动态代理开发扫描 -->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <property name="basePackage" value="com.sunwii.mybatis.mapper" />
- </bean>
- <!-- 事务管理器 -->
- <bean id="transactionManager"
- class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource"
- value="#{sessionFactory.configuration.environment.dataSource}" />
- </bean>
- <!-- 注解事务 -->
- <tx:annotation-driven
- transaction-manager="transactionManager" />
- <!-- Service 扫描 -->
- <context:component-scan
- base-package="com.sunwii.mybatis.service.impl" />
- </beans>
关键点就在于: 将 org.apache.ibatis.session.SqlSessionFactory 用 Spring 容器创建出来
有 3 种方式:
1. mybatis.spring 整合包的方式: 正常来说可以直接配置 org.mybatis.spring.SqlSessionFactoryBean 来创建, 但本例为了减少配置量, 减少 Mybatis 的变动, 以及简洁起见, 使用了自定义方式.
2. 自定义动态工厂方式: 使用了自定义的动态工厂 SessionFactoryBuilder(从单独使用的 Mybatis 工具类中修改而来) 方法来创建 SqlSessionFactory.
这样的话, 原先在 Mybatis 主配置里配置的 JDBC, 数据源之类的, 不需移动到 Spring 中, 而事务管理器中只需要引 Spring 表达式引用即可: #{sessionFactory.configuration.environment.dataSource}.
3. 自定义 FactoryBean<SqlSessionFactory > 接口方式: 这就跟 mybatis-spring.jar 包整合的创建方式相类似 (主要代码跟自定义动态工厂方法差不多, 但需要实现好几个 FactoryBean 的方法, 代码稍多, 为简洁起见, 不使用)
最后就是 Service 中直接使用 Mapper 接口了:
- @Service
- public class RoleServiceImpl implements RoleService {
- @Autowired
- private RoleMapper roleMapper;
- @Autowired
- private RolePermissionMapper rolePermissionMapper;
- @Autowired
- private PermissionMapper permissionMapper;
- @Override
- @Transactional
- public int insertRole(Role role) {
- int rs = 0;
- rs = roleMapper.insert(role);
- //Permission permission = permissionMapper.selectById(56);
- //role.setPermissions(Arrays.asList(permission));
- Permission permission = new Permission();
- permission.setName("permission-" + 1);
- permissionMapper.insert(permission);
- // 0 / 0 测试事务回滚
- new Integer(0 / 1);
- RolePermission rolePermission = new RolePermission();
- rolePermission.setRole(role);
- rolePermission.setPermission(permission);
- rolePermissionMapper.insert(rolePermission);
- return rs;
- }
- @Override
- public Role getRoleById(Integer id) {
- return roleMapper.selectById(id);
- }
- }
说明:
由于采用了 Mapper 接口的方式来进行开发, org.mybatis.spring.mapper.MapperScannerConfigurer 在处理接口的时候,
经处理后的 Mapper 接口层用到了 SqlSessionDaoSupport 及 SqlSessionTemplate, 所以不需要担心 SqlSession 线程安全问题, 并且也不需要直接使用 SqlSession, 直接使用的是 Mapper 接口.
如果不采用 Mapper 接口开发, 为了 SqlSession 线程安全问题, 可以有几种处理方式:
1. 可以自定义 ThreadLocal<SqlSession>, 代码较多, 事务管理麻烦, 不推荐. 上边所有配置不变
2. 让 daoImpl 实现 SqlSessionDaoSupport 并注入 SqlSessionFactory 就可以了. 上边所有配置不变
3. 让 daoImpl 中注入 SqlSessionTemplate 就可以了. 上边所有配置不变, 但多加一个 SqlSessionTemplate 的配置.
----------END OF 不需要怎么修改配置的 Mybatis 整合 Spring 要点 ------------------
来源: https://www.cnblogs.com/dreamyoung/p/11799407.html