最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis的核心架構(gòu)及源碼解讀

 更新時間:2023年08月25日 09:58:52   作者:摳腳的大灰狼  
這篇文章主要介紹了Mybatis的核心架構(gòu)及源碼解讀,mybatis是一款半自動化的持久層框架,它封裝了JDBC操作,支持定制化SQL,高級映射,但它的數(shù)據(jù)庫無關(guān)性較低,需要的朋友可以參考下

概述

mybatis是什么?

mybatis是一款半自動化的持久層框架,它封裝了JDBC操作,支持定制化SQL,高級映射。但它的數(shù)據(jù)庫無關(guān)性較低,2個不同的數(shù)據(jù)庫,可能需要2套SQL語句

mybatis的基本使用?

  • 編寫全局配置文件
  • 編寫mapper映射文件
  • 加載配置文件,生成SqlSessionFactory
  • 創(chuàng)建SqlSession,通過SqlSession調(diào)用mapper映射文件中的SQL語句來執(zhí)行數(shù)據(jù)庫操作

架構(gòu)流程

三層結(jié)構(gòu)

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LfGIOhPg-1573726013288)(C:\Users\Vergi\Desktop\3level-architech.png)]

接口層

使用SqlSession和Mapper接口,來完成對SQL語句的調(diào)用,日常開發(fā)中主要接觸這一層

數(shù)據(jù)處理層

這一層是mybatis進行的工作,負責(zé)SQL語句組裝,查詢參數(shù)綁定,結(jié)果集映射

基礎(chǔ)支撐層

這一層可以理解為我們?nèi)峙渲美锏膬?nèi)容。包括數(shù)據(jù)庫連接信息,事務(wù)管理信息,配置緩存,編寫mapper映射文件中的SQL語句等

工作流程

  • 向SqlSession傳入SQL語句的id,以及查詢參數(shù)
  • 找到待執(zhí)行的SQL信息,交給Executor執(zhí)行器處理
  • Executor負責(zé)對SQL語句進行組裝拼接,后交給StatementHandler處理
  • StatementHandler封裝了JDBC的操作,它負責(zé)根據(jù)SQL信息,生成對應(yīng)的Statement,并利用ParameterHandler進行查詢參數(shù)的解析與綁定,后執(zhí)行查詢
  • StatemenHandler查詢完畢,將結(jié)果集交由ResultSetHandler進行結(jié)果集信息的解析與封裝處理(參數(shù)解析,結(jié)果集解析,都會用TypeHandler來做類型轉(zhuǎn)換,java類型與JDBC類型)

源碼部分

全局配置文件解析過程

  • 獲得配置文件的InputStream,創(chuàng)建Document對象
  • 利用Xpath語法,解析各個配置節(jié)點
  • 將信息封裝到Configuration對象中,生成SqlSessionFactory

源碼過程

SqlSessionFactoryBuilder # build 
 |- XMLConfigBuilder # parse 
   |- XMLConfigBuilder # parseConfiguration

mapper映射文件解析過程

  • 一個mapper.xml映射文件,由namespace屬性作為唯一標(biāo)識
  • 擁有namespace屬性的mapper.xml映射文件,會被注冊到Configuration中的mapperRegistry中,以便后續(xù)生成mapper代理對象
  • 一個mapper.xml,對應(yīng)一個MapperBuilderAssistant對象,這個builderAssistant對象解析并保存了該mapper.xml中的公共標(biāo)簽,如parameterMap,resultMap,cache,sql,這些標(biāo)簽可能在某個CRUD標(biāo)簽里被使用
  • 解析CRUD標(biāo)簽,即 select | update | insert | delete 標(biāo)簽,一個CRUD標(biāo)簽,被封裝成一個MappedStatement對象,以標(biāo)簽的id屬性作為唯一標(biāo)識,MappedStatement里包含了SQL語句信息,參數(shù)映射信息,結(jié)果集映射信息

源碼過程

XMLConfigBuilder # mapperElement
 |- XMLMapperBuilder # parse
   |- XMLMapperBuilder # configurationElement

SQL加載與組裝過程

SQL裝載

  • 在解析mapper映射文件中的CRUD標(biāo)簽時,對SQL語句進行了解析和封裝
  • 將一個CRUD標(biāo)簽,封裝成SqlNode,并將其子元素(可能是文本節(jié)點,也可能是動態(tài)SQL節(jié)點),也封裝成SqlNode,利用組合模式,對這些SqlNode進行組裝,最終將SqlNode和Configuration封裝在一起,形成SqlSource
  • 有動態(tài)SQL標(biāo)簽的,或者有${} 的,會被封裝成DynamicSqlSource,其余的,會被封裝成RawSqlSource(在Executor執(zhí)行時都會解析并封裝成StaticSqlSource)
  • SqlSource和其他信息,一起被封裝為MapperStatement,一個CRUD標(biāo)簽,對應(yīng)一個MappedStatement

源碼過程

XMLMapperBuilder # buildStatementFromContext
 |- XMLStatementBuilder # parseStatementNode
   |- XMLLanguageDriver # createSqlSource 
     |- XMLScriptBuilder # parseScriptNode

SQL組裝

  • 調(diào)用Executor進行執(zhí)行時,會查找對應(yīng)的MappedStatement,并調(diào)用其SqlSource的getBoundSql,進行SQL語句的組裝,并封裝查詢參數(shù)
  • 調(diào)用getBoundSql方法時,會調(diào)用SqlNode的apply方法,不同SqlNode子類,會采取不同方式,解析動態(tài)SQL標(biāo)簽,并進行SQL語句拼接,并將#{}替換為 ? ,將${}做字符串拼接,之后封裝到StaticSqlSource,此時已經(jīng)將SQL語句解析并組裝,這個StaticSqlSource里就是SQL語句以及查詢參數(shù)

源碼過程

CachingExecutor # query
 |- MappedStatement # getBoundSql
  |- DynamicSqlSource # getBoundSql
   |- SqlNode # apply // 動態(tài)SQL的組裝,以及將${}進行字符串拼接
   |- SqlSourceBuilder # parse //這里是將#{}替換成 ?
   //組裝完成后封裝成StaticSqlSource
   //并調(diào)用StaticSqlSource的getBoundSql
   //new 一個新的BoundSql,傳入組裝好的SQL語句,以及查詢參數(shù)

執(zhí)行查詢過程

  • 從Configuration中根據(jù)id,取出一個MappedStatement
  • 將MappedStatement交由Executor處理
  • Executor中調(diào)用MappedStatement的getBoundSql,獲取組裝好的SQL語句,以及查詢參數(shù)
  • 根據(jù)查詢參數(shù),MappedStatement等信息,構(gòu)建出一個StatementHandler出來
  • StatementHandler新建一個Statement對象,并借助ParameterHandler完成對Statement的入?yún)⒔壎?/li>
  • 執(zhí)行查詢,并將結(jié)果集交由ResultSetHandler處理

源碼過程

DefaultSqlSession # selectList
 |- CachingExecutor # query
   |- BaseExecutor # query
     |- BaseExecutor # queryFromDatabase
       |- SimpleExecutor # doQuery
         |- Configuration # newStatementHandler
         |- SimpleExecutor # prepareStatement
         |- StatementHandler # query

緩存過程

  • 執(zhí)行查詢時,首先是走CachingExecutor,CachingExecutor中檢查是否開啟二級緩存,若開啟,則會負責(zé)二級緩存數(shù)據(jù)的存取
  • 若沒開啟二級緩存,或二級緩存沒命中,進入到BaseExecutor中,嘗試從一級緩存中拿數(shù)據(jù),若一級緩存中也沒有,則會訪問數(shù)據(jù)庫
  • 二級緩存是mapper級別的,即一個mapper,對應(yīng)一個二級緩存。在源碼中,二級緩存是被MappedStatement持有。二級緩存是通過mapper映射文件中的<cache/> 標(biāo)簽開啟的
  • 一級緩存無法關(guān)閉,但可以在全局配置中設(shè)置<setting name="localCacheScope" value="STATEMENT"/> 來使其失效(每次執(zhí)行操作都會清空一級緩存)

源碼過程

//二級緩存
CachingExecutor # query
 |- MappedStatement # getCache//獲取該mapper下的二級緩存
 |- TransactionalCacheManager # getObject //查找緩存中是否有數(shù)據(jù)
   |- TransactionalCache # getObject //查找緩存中是否有數(shù)據(jù)
 |-TransactionalCacheManager # putObject //存入二級緩存
   |- TransactionalCache # getObject
//若二級緩存未命中,走一級緩存
BaseExecutor # query
  |- PerpetualCache # getObject //從一級緩存中取數(shù)據(jù)

延遲加載過程

  • 在查詢結(jié)束后,調(diào)用ResultSetHandler對結(jié)果集進行處理時,若發(fā)現(xiàn)開啟了延遲加載,且有嵌套查詢,則會對結(jié)果生成一個代理對象
  • 當(dāng)調(diào)用結(jié)果的get方法,訪問延遲加載的數(shù)據(jù)時,發(fā)現(xiàn)數(shù)據(jù)為空,則獲取其MappedStatement,執(zhí)行一次查詢,把查詢結(jié)果set到主對象中

源碼過程

DefaultResultSetHandler # createResultObject
 |- Configuration # getProxyFactory
 |- JavassistProxyFactory # createProxy
 // 默認是使用JavassistProxyFactory

獲取Mapper代理過程

  • 調(diào)用Configuration中的mapperRegistry來查找這個mapper的類信息,會找到一個MapperProxyFactory對象
  • 使用JDK內(nèi)置的動態(tài)代理,調(diào)用java.lang.reflect下的Proxy來生成一個代理類

源碼過程

DefaultSqlSession # getMapper
 |- MapperRegistry # getMapper
  |- MapperProxyFactory # newInstance
    |- MapperProxy # 構(gòu)造函數(shù)
    |- Proxy.newProxyInstance

mybatis插件過程

mybatis的插件會對以下幾個類起作用

  • Executor
  • StatementHandler
  • ParameterHandler
  • ResultSetHandler

實現(xiàn)Interceptor接口,覆寫intercept方法,在intercept方法中完成插件的攔截邏輯。

并覆寫plugin方法,在plugin方法中調(diào)用Plugin.wrap來生成一個代理對象并返回,即可。

底層也是使用的JDK動態(tài)代理

源碼流程

//以Executor為例
DefaultSqlSessionFactory # openSession
  |- Configuration # newExecutor
    |- InterceptorChain # pluginAll

類關(guān)系總結(jié)

配置文件解析相關(guān)

  • BaseBuilder
  • XMLConfigBuilder
  • XMLMapperBuilder
  • 持有一個MapperBuilderAssistant
  • XMLStatementBuilder
  • XMLScriptBuilder

SQL組裝相關(guān)

  • SqlSource
    • DynamicSqlSource :
      • 含有動態(tài)SQL,或 ${} ,會被解析封裝成這個類
    • RawSqlSource :
      • 不含動態(tài)SQL,以及${} ,會被解析封裝成這個類
    • StaticSqlSource
      • Executor執(zhí)行查詢,調(diào)用getBoundSql方法時,組裝好SQL語句,與查詢參數(shù)一同封裝起來,為這個類
  • SqlNode
    • TextSqlNode 文本節(jié)點
    • StaticTextSqlNode 文本節(jié)點,且文本不包含 ${}
    • IfSqlNode
    • ForEachSqlNode
    • ChooseSqlNode
    • TrimSqlNode
    • 有2個子類,分別是
      • WhereSqlNode
      • SetSqlNode
    • MixedSqlNode作為根節(jié)點,其有一個 List<SqlNode> 字段

執(zhí)行相關(guān)

  • Executor

    • BaseExecutor

      其有3個子類,分別是

      • SimpleExecutor
      • ReuseExecutor
      • BatchExecutor
    • CachingExecutor

  • StatementHandler
    • RoutingStatementHandler

      僅作路由選擇功能

    • BaseStatementHandler

      其有3個子類,分別是

      • SimpleStatementHandler
      • PreparedStatementHandler
      • CallableStatementHandler
  • ParameterHandler

  • ResultSetHandler

  • Cache

    • PerpetualCache
    • LruCache
    • FifoCache
    • SerializedCache
    • LoggingCache
    • SynchronizedCache
    • SoftCache
    • WeakCache
    • TransactionalCache

到此這篇關(guān)于Mybatis的核心架構(gòu)及源碼解讀的文章就介紹到這了,更多相關(guān)Mybatis的核心架構(gòu)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 教你輕松制作java音樂播放器

    教你輕松制作java音樂播放器

    這篇文章主要介紹了如何編寫屬于自己的java音樂播放器,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • spring boot實現(xiàn)軟刪除的示例代碼

    spring boot實現(xiàn)軟刪除的示例代碼

    這篇文章主要介紹了spring boot實現(xiàn)軟刪除的示例代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07
  • Java swing實現(xiàn)音樂播放器桌面歌詞字體變色效果

    Java swing實現(xiàn)音樂播放器桌面歌詞字體變色效果

    這篇文章主要為大家詳細介紹了Java swing實現(xiàn)音樂播放器桌面歌詞字體變色效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • 微信支付之公眾號支付(java實現(xiàn))

    微信支付之公眾號支付(java實現(xiàn))

    這篇文章主要介紹了微信支付之公眾號支付(java實現(xiàn)),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • @JsonFormat?和?@DateTimeFormat?時間格式化注解(場景示例代碼)

    @JsonFormat?和?@DateTimeFormat?時間格式化注解(場景示例代碼)

    這篇文章主要介紹了@JsonFormat和@DateTimeFormat時間格式化注解,本文通過場景示例代碼詳解給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • Java中的xxl-job調(diào)度器線程池工作機制

    Java中的xxl-job調(diào)度器線程池工作機制

    xxl-job通過快慢線程池分離短時與長時任務(wù),動態(tài)降級超時任務(wù)至慢池,結(jié)合異步觸發(fā)和資源隔離機制,提升高頻調(diào)度的性能與穩(wěn)定性,支撐高并發(fā)場景下的可靠任務(wù)執(zhí)行,本文給大家介紹Java: xxl-job調(diào)度器線程池工作機制,感興趣的朋友一起看看吧
    2025-07-07
  • Java解壓zip文件完整代碼分享

    Java解壓zip文件完整代碼分享

    這篇文章主要介紹了Java解壓zip文件完整代碼分享,向大家分享了兩部分代碼示例,具有一定參考價值,需要的朋友可以了解下。
    2017-11-11
  • SpringBoot登錄、退出、獲取用戶信息的session處理方案

    SpringBoot登錄、退出、獲取用戶信息的session處理方案

    這篇文章主要介紹了SpringBoot登錄、退出、獲取用戶信息的session處理,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • 什么是Maven及如何配置國內(nèi)源實現(xiàn)自動獲取jar包的操作

    什么是Maven及如何配置國內(nèi)源實現(xiàn)自動獲取jar包的操作

    本文介紹了Maven的基本概念,包括項目構(gòu)建、依賴管理、倉庫管理以及如何設(shè)置國內(nèi)源,通過Maven,開發(fā)者可以自動化管理項目的依賴和構(gòu)建流程,提高開發(fā)效率,感興趣的朋友跟隨小編一起看看吧
    2024-11-11
  • 詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel)

    詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel)

    這篇文章主要介紹了詳解SpringBoot Redis自適應(yīng)配置(Cluster Standalone Sentinel),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07

最新評論

无棣县| 东至县| 彭州市| 丰台区| 连江县| 建阳市| 贵定县| 仁寿县| 郁南县| 武宣县| 项城市| 永顺县| 霍山县| 昌平区| 西充县| 鹤壁市| 曲阳县| 邛崃市| 明溪县| 鄂尔多斯市| 阿尔山市| 巩义市| 连江县| 辛集市| 平远县| 扎鲁特旗| 玉门市| 洛扎县| 大连市| 新邵县| 商河县| 长寿区| 桃园市| 闵行区| 荆门市| 聂荣县| 泽州县| 星子县| 乐业县| 霸州市| 大洼县|