Java進(jìn)階-MyBatis

一、參考資料

MyBatis官網(wǎng)
玩轉(zhuǎn) MyBatis:深度解析與定制
Mybatis介紹
為什么建議框架源碼學(xué)習(xí)從Mybatis開始

二、整體結(jié)構(gòu)

image.png

三、配置文件

https://mybatis.org/mybatis-3/zh/configuration.html#settings

3.1 配置文件加載

InputStream xml = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(xml);
  • 通過ClassLoader獲取到全局配置文件的二進(jìn)制流
  • XMLConfigBuilder構(gòu)建SqlSessionFactory
MyBatis配置文件加載.png

3.2 Mapper.xml的解析

XMLConfigBuilder#parseConfiguration
mapperElement(root.evalNode("mappers"));
Mapper.xml解析.png

四、緩存

??一級(jí)緩存基于SqlSession,可以直接創(chuàng)建SqlSessionFactory,并從中開啟一個(gè)新的SqlSession,默認(rèn)情況下它會(huì)自動(dòng)開啟事務(wù)。

??一級(jí)緩存失效的情景:

  • 跨SqlSession的一級(jí)緩存不共享
  • 兩次相同的查詢間有DML操作
  • 手動(dòng)清空了一級(jí)緩存

??SpringFramework/SpringBoot整合MyBatis后,Service方法中沒有開啟事務(wù)時(shí),每次調(diào)用Mapper查詢數(shù)據(jù)時(shí),底層都會(huì)創(chuàng)建一個(gè)全新的SqlSession去查數(shù)據(jù)庫(kù)。

BaseExecutor#query
protected PerpetualCache localCache;
  • SqlSession關(guān)閉時(shí),一級(jí)緩存的數(shù)據(jù)進(jìn)入二級(jí)緩存
  • 二級(jí)緩存中有數(shù)據(jù)時(shí),直接取出,不會(huì)預(yù)先開啟Connection
  • 二級(jí)緩存基于nameSpace級(jí)別
CachingExecutor#query

private final TransactionalCacheManager tcm = new TransactionalCacheManager();

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, 
                         ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    Cache cache = ms.getCache();
    if (cache != null) {
        flushCacheIfRequired(ms);
        if (ms.isUseCache() && resultHandler == null) {
            ensureNoOutParams(ms, boundSql);
            List<E> list = (List<E>) tcm.getObject(cache, key);
            if (list == null) {
                list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
                tcm.putObject(cache, key, list); // issue #578 and #116
            }
            return list;
        }
    }
    return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

?? TransactionalCacheManager:二級(jí)緩存應(yīng)該是基于事務(wù)提交的,只有事務(wù)提交后,數(shù)據(jù)庫(kù)的數(shù)據(jù)確定沒有問題,這個(gè)時(shí)候SqlSession中的一級(jí)緩存數(shù)據(jù)也是準(zhǔn)確的,這樣才能把一級(jí)緩存的數(shù)據(jù)寫入到二級(jí)緩存中。

?? 二級(jí)緩存在寫入時(shí)已經(jīng)執(zhí)行了一次基于jdk的序列化動(dòng)作,每次從二級(jí)緩存取數(shù)據(jù)時(shí),會(huì)再執(zhí)行一次反序列化,將字節(jié)數(shù)組轉(zhuǎn)為緩存數(shù)據(jù)對(duì)象。

五、日志

??Logger增強(qiáng)類-動(dòng)態(tài)代理。

  • PreparedStatementLogger
  • ConnectionLogger
  • ResultSetLogger

六、Spring整合MyBatis

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <!-- MyBatis全局配置文件 -->
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <property name="typeAliasesPackage" value="com.linkedbear.mybatis.entity"/>
</bean>

??SqlSessionFactoryBean:只負(fù)責(zé)mapper.xml的處理。

public class SqlSessionFactoryBean
       implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

   // ......

   private Resource configLocation;

   private Configuration configuration;
  • 幾乎可以代替MyBatis全局配置文件
  • 可以傳入全局配置文件,供MyBatis解析和處理
  • 代替MyBatis處理數(shù)據(jù)源和事務(wù)工廠
  • 只處理和解析mapper.xml

??MapperScannerConfigurer:掃描Mapper接口。

public class MapperScannerConfigurer
        implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {

    private SqlSessionFactory sqlSessionFactory;

    private SqlSessionTemplate sqlSessionTemplate;

    private String sqlSessionFactoryBeanName;

    private String sqlSessionTemplateBeanName;

??ClassPathMapperScanner,它會(huì)執(zhí)行包掃描的動(dòng)作,并且將掃描到的Mapper接口都收集起來(lái),構(gòu)造成MapperFactoryBeanMapper,注入到SqlSessionFactory和SqlSessionTemplate。

七、生命周期

??整體結(jié)構(gòu):

image.png

??Executor類結(jié)構(gòu):

image.png
  • CRUD操作
  • 事務(wù)控制和獲取
  • 二級(jí)緩存的控制
  • 延遲加載

??selectList的整體調(diào)用時(shí)序圖:

image.png
  • SqlSource中傳入?yún)?shù),返回BoundSql的過程,會(huì)將動(dòng)態(tài)SQL解析轉(zhuǎn)化為可以執(zhí)行的帶占位符的SQL語(yǔ)句。
image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Mybatis-9.28 環(huán)境: JDK1.8 Mysql 5.7 maven 3.6.1 IDEA 回顧: JD...
    眼若繁星丶閱讀 292評(píng)論 0 1
  • 1、MyBatis簡(jiǎn)介 MyBatis 是一款優(yōu)秀的持久層框架 中文官網(wǎng):https://mybatis.org/...
    CHeng_c0e9閱讀 604評(píng)論 0 0
  • Mybatis-9.28 環(huán)境: JDK1.8 Mysql 5.7 maven 3.6.1 IDEA 回顧: JD...
    友人Ay閱讀 420評(píng)論 0 1
  • 1. MyBatis簡(jiǎn)介 MyBatis提供了數(shù)據(jù)庫(kù)查詢的自動(dòng)對(duì)象綁定功能;SQL寫在XML中,便于統(tǒng)一管理和優(yōu)化...
    皇天閱讀 464評(píng)論 0 0
  • 閱讀需要20分鐘 一、MyBatis的開始 從官方文檔[https://mybatis.org/mybatis-3...
    知向誰(shuí)邊閱讀 318評(píng)論 0 0

友情鏈接更多精彩內(nèi)容