聊聊Mybatis与Spring的整合

举报
周杰伦本人 发表于 2022/08/30 21:11:03 2022/08/30
【摘要】 聊聊Mybatis与Spring的整合Mybatis与Spring整合需要一个依赖包 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> </dependency>我们分析一下这个包下面的一些类 SqlSessionFactoryBeanSql...

聊聊Mybatis与Spring的整合

Mybatis与Spring整合需要一个依赖包

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
    </dependency>

我们分析一下这个包下面的一些类

SqlSessionFactoryBean

SqlSessionFactoryBean类是读取Mybatis的配置信息,初始化Configuration全局配置对象和创建SqlSessionFactory对象的功能

我们看一下它的创建SqlSessionFactory方法,对应方法是buildSqlSessionFactory(),方法太长我就不贴了,具体看一下它的逻辑:

  1. 创建XMLConfigBuilder对象,读取配置文件
  2. 如果定义了typeAliasesPackage别名属性,就扫描并注册类的别名
  3. 如果定义了插件拦截器,就添加拦截器到Configuration对象中
  4. 如果配置了自定义的类型处理器TypeHandler,就进行注册,TypeHandler就是实现java类型和jdbc类型互相转换的
  5. 如果数据源不为空,配置数据源到Configuration对象中
  6. 如果缓存不为空,配置缓存到Configuration对象中
  7. 如果事务工厂为空的话,使用SpringManagedTransactionFactory创建事务工厂
  8. 设置Environment环境变量
  9. 根据mapperLocations的配置,加载Mapper.xml配置文件,通过xmlMapperBuilder进行解析Mapper.xml
  10. 利用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中

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。