四、spring 集成myBatis

1、基本使用

基础集成使用: 

1、配置 SqlSessionFactoryBean

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
</bean>

2、配置 MapperFactoryBean

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
    <property name="mapperInterface" value="com.tuling.mybatis.dao.UserMapper"/>
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>

简化Mapper 配置

//如果每个mapper 接口都配置MapperFactoryBean 相当麻烦 可以通过 如下配置进行自动扫描
<mybatis:scan base-package="com.tuling.mybatis.dao"/>
//其与 spring bean 注解扫描机制类似,所以得加上注解扫描开关的配置
<context:annotation-config/>

3、获取mapper 对象执行业务方法

context = new ClassPathXmlApplicationContext("spring.xml");
UserMapper mapper = context.getBean(UserMapper.class);
System.out.println(mapper.selectByid(1));

 对象说明:

FactoryBean:

工厂Bean 用于 自定义生成Bean对象,当在ioc 中配置FactoryBean 的实例时,最终通过bean id 对应的是FactoryBean.getObject()实例,而非FactoryBean 实例本身

SqlSessionFactoryBean:

生成SqlSessionFactory 实例,该为单例对象,作用于整个应用生命周期。常用属性如下:

  • dataSource:   数据源(必填)
  • configLocation:指定mybatis-config.xml 的内容,但其设置的<dataSource> <properties> <environments> 将会失效(选填)
  • mapperLocations:指定mapper.xml 的路径,相当于mybatis-config.xml 中<mappers> 元素配置,(选填)

MapperFactoryBean:

生成对应的Mapper对象,通常为单例,作用于整个应用生命周期。常用属性如下:

  • mapperInterface:mapper 接口      (必填)
  • sqlSessionFactory:会话工厂实例 引用 (必填)

关于Mapper 单例情况下是否存在线程安全的问题?

 在原生的myBatis 使用中mapper 对象的生命期是与SqlSession同步的,不会存在线程安全问题,现在单例的mapper 是如何解决线程安全的问题的呢?

答: mapper虽然是单例,但是每次执行语句会创建单独的sqlsession,具体通过下面流程解析

2、核心流程解析

SQL session 集成结构: 

初始化流程

创建 会话模板 SqlSessionTemplate

>org.mybatis.spring.mapper.MapperFactoryBean#MapperFactoryBean()

> org.mybatis.spring.support.SqlSessionDaoSupport#setSqlSessionFactory

> org.mybatis.spring.SqlSessionTemplate#SqlSessionTemplate()

>org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor 

创建接口

> org.mybatis.spring.mapper.MapperFactoryBean#getObject

> org.mybatis.spring.SqlSessionTemplate#getMapper

>org.apache.ibatis.session.Configuration#getMapper

执行查询

>com.tuling.mybatis.dao.UserMapper#selectByid

 >org.apache.ibatis.binding.MapperProxy#invoke

 >org.mybatis.spring.SqlSessionTemplate#selectOne(java.lang.String)

 >org.mybatis.spring.SqlSessionTemplate#sqlSessionProxy#selectOne(java.lang.String)

 >org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor#invoke

 >org.mybatis.spring.SqlSessionUtils#getSqlSession()

 >org.apache.ibatis.session.SqlSessionFactory#openSession()

org.apache.ibatis.session.defaults.DefaultSqlSession#selectOne()

 每次查询都会创建一个新的 SqlSession 会话,一级缓存还会生效吗?

 答:通过前几次课我们了解到 一级缓存的条件是必须相同的会话,所以缓存通过和spring 集成之后就不会生效了。除非使用spring 事务 这时就不会在重新创建会话

3、事务使用

spring 事物没有针对myBatis的配置,都是一些常规事物配置:

<!--添加事物配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <constructor-arg ref="dataSource"/>
</bean>
<!--事物注解配置-->
<tx:annotation-driven/>

事物与SqlSession 集成原理:

其原理前面讲查询流程时有所涉及。每次执行SQL操作前都会通过 getSqlSession 来获取会话。其主要逻辑是 如果当前线程存在事物,并且存在相关会话,就从ThreadLocal中取出 。如果没就从创建一个 SqlSession 并存储到ThreadLocal 当中,共下次查询使用。

相关源码:

org.mybatis.spring.SqlSessionUtils#getSqlSession()

org.springframework.transaction.support.TransactionSynchronizationManager#getResource

org.mybatis.spring.SqlSessionUtils#sessionHolder

org.apache.ibatis.session.SqlSessionFactory#openSession()

org.mybatis.spring.SqlSessionUtils#registerSessionHolder

org.springframework.transaction.support.TransactionSynchronizationManager#isSynchronizationActive

org.springframework.transaction.support.TransactionSynchronizationManager#bindResource

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值