5、Mybatis 第三方框架集成

知識點:spring 集成myBatisjava

1、spring 集成myBatis

核心使用:

基礎集成使用: 一、配置 SqlSessionFactoryBeanspring

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

二、配置 MapperFactoryBeansql

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

三、獲取mapper 對像執行業務方法apache

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 的內容,但其設置的 將會失效(選填)
  • mapperLocations:指定mapper.xml 的路徑,至關於mybatis-config.xml 中 元素配置,(選填)

MapperFactoryBean: 生成對應的Mapper對像,一般爲單例,做用於整個應用生命週期。經常使用屬性以下:安全

  • mapperInterface:mapper 接口 (必填)
  • sqlSessionFactory:會話工廠實例 引用 (必填)

關於Mapper 單例狀況下是否存在線程安全的問題? 在原生的myBatis 使用中mapper 對像的生命期是與SqlSession同步的,不會存在線程安全問題,如今單例的mapper 是如何解決線程安全的問題的呢?bash

核心流程解析:

SQL Session 集成結構: session

初始化流程 // 建立 會話模板 SqlSessionTemplatemybatis

>org.mybatis.spring.mapper.MapperFactoryBean#MapperFactoryBean()
>org.mybatis.spring.support.SqlSessionDaoSupport#setSqlSessionFactory
>org.mybatis.spring.SqlSessionTemplate#SqlSessionTemplate()
>org.mybatis.spring.SqlSessionTemplate.SqlSessionInterceptor 
複製代碼

// 建立接口app

>org.mybatis.spring.mapper.MapperFactoryBean#getObject
>org.mybatis.spring.SqlSessionTemplate#getMapper
>org.apache.ibatis.session.Configuration#getMapper
複製代碼

// 執行查詢

>com.niuh.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 事物 這時就不會在從新建立會話。

事物使用 :

spring 事物沒有針對myBatis的配置,都是一些常規事物配置:

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

添加事物註解:

@Transactional()
public User getUser2(Integer id) {
    userMapper.selectByid(id);
    return userMapper.selectByid(id);
}
複製代碼

執行測試發現 當調用getUser2 方法時兩次查詢不在重複建立 sqlSession。而是共用一個直到getUser2 方法結束。

事物與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
複製代碼

簡化Mapper 配置

若是每一個mapper 接口都配置*MapperFactoryBean *至關麻煩 能夠經過 以下配置進行自動掃描

 <mybatis:scan base-package="com.niuh.mybatis.dao"/>
複製代碼

其與 spring bean 註解掃描機制相似,因此得加上註解掃描開關的配置

<context:annotation-config/>
複製代碼
相關文章
相關標籤/搜索