聊聊Mybatis与Spring的整合
Posted 周杰伦本人
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊聊Mybatis与Spring的整合相关的知识,希望对你有一定的参考价值。
@[TOC]
聊聊Mybatis与Spring的整合
Mybatis与Spring整合需要一个依赖包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
我们分析一下这个包下面的一些类
SqlSessionFactoryBean
SqlSessionFactoryBean类是读取Mybatis的配置信息,初始化Configuration全局配置对象和创建SqlSessionFactory对象的功能
我们看一下它的创建SqlSessionFactory方法,对应方法是buildSqlSessionFactory(),方法太长我就不贴了,具体看一下它的逻辑:
- 创建XMLConfigBuilder对象,读取配置文件
- 如果定义了typeAliasesPackage别名属性,就扫描并注册类的别名
- 如果定义了插件兰姐器,就添加兰姐器到Configuration对象中
- 如果配置了自定义的类型处理器TypeHandler,就进行注册,TypeHandler就是实现java类型和jdbc类型互相转换的
- 如果数据源不为空,配置数据源到Configuration对象中
- 如果缓存不为空,配置缓存到Configuration对象中
- 如果事务工厂为空的话,使用SpringManagedTransactionFactory创建事务工厂
- 设置Environment环境变量
- 根据mapperLocations的配置,加载Mapper.xml配置文件,通过xmlMapperBuilder进行解析Mapper.xml
- 利用Configuration对象创建DefaultSqlSessionFactory实例
SpringManagedTransactionFactory
第七步中我们使用SpringManagedTransactionFactory,SpringManagedTransactionFactory是创建SpringManagedTransaction对象的类,SpringManagedTransaction有个isConnectionTransactional字段,isConnectionTransactional是用来标识事务是否有spring来进行管理,SpringManagedTransaction代替mybatis的JdbcTransaction,调用DataSourceUtils.getConnection()方法从ThreadLocal中获取jdbc connection并执行sql。
SqlSessionTemplate
SqlSessionTemplate实现了SqlSession接口,它代替了Mybatis的DefaultSqlSession,它是线程安全的,单个实例可以被所有 DAO 共享
使用的话配置如下:
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
</bean>
SqlSessionTemplate有个SqlSession成员变量,是个代理对象,
this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(), new Class[] SqlSession.class , new SqlSessionInterceptor());利用的同样是jdk动态代理,SqlSessionInterceptor实现了InvocationHandler接口,重写invoke()方法:从事务管理器中获取SqlSession,执行完相应方法后看看事务是否由Spring管理,如果不是就立即提交,DataSourceTransactionManager是Spring的事务管理器
MapperScannerConfigurer
MapperScannerConfigurer是扫描器,扫描Mybatis中的Mapper.xml配置文件,它会把扫描到的 Mapper 接口创建成 MapperFactoryBean对象,它实现了BeanDefinitionRegistryPostProcessor接口,这样在Spring初始化的时候就会调用postProcessBeanDefinitionRegistry()方法,方法中扫描指定包和子包,找到符合条件的BeanDefinitionHolder对象,改造成MapperFactoryBean,通过MapperFactoryBean可以将Mapper接口直接注入到Service中,MapperFactoryBean初始化后进行属性填充的时候调用checkDaoConfig()方法:
@Override
protected void checkDaoConfig()
super.checkDaoConfig();
notNull(this.mapperInterface, "Property mapperInterface is required");
Configuration configuration = getSqlSession().getConfiguration();
if (this.addToConfig && !configuration.hasMapper(this.mapperInterface))
try
configuration.addMapper(this.mapperInterface);
catch (Exception e)
logger.error("Error while adding the mapper " + this.mapperInterface + " to configuration.", e);
throw new IllegalArgumentException(e);
finally
ErrorContext.instance().reset();
checkDaoConfig()方法中会将mapper接口添加到Configuration对象中,然后通过getObject()方法可以获取到Mapper接口的代理对象
总结
这篇文章主要讲了Spring与Mybatis整合包下的几个类,SqlSessionFactoryBean用来创建SqlSessionFactory,它的buildSqlSessionFactory()方法读取了全局配置文件的信息并解析添加到Configuration对象中,SpringManagedTransactionFactory用来创建SpringManagedTransaction代替Mybatis中的JdbcTransaction,SqlSessionTemplate实现SqlSession接口,线程安全,成员变量sqlSessionProxy是代理对象,利用代理类SqlSessionInterceptor进行拦截,对spring管理的事务不进行立即提交,MapperScannerConfigurer用来扫描mapper接口并创建MapperFactoryBean对象,这样mapper接口可以直接注入Service中
以上是关于聊聊Mybatis与Spring的整合的主要内容,如果未能解决你的问题,请参考以下文章