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:
SqlSessionFactoryBean:
MapperFactoryBean:
关于Mapper 单例情况下是否存在线程安全的问题?
在原生的myBatis 使用中mapper 对象的生命期是与SqlSession同步的,不会存在线程安全问题,现在单例的mapper 是如何解决线程安全的问题的呢?
答: mapper虽然是单例,但是每次执行语句会创建单独的sqlsession,具体通过下面流程解析
2、核心流程解析
SQL session 集成结构:
初始化流程
创建 会话模板 SqlSessionTemplate
创建接口
执行查询
每次查询都会创建一个新的 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 当中,共下次查询使用。
相关源码: