欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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進行的工作,負責SQL語句組裝,查詢參數(shù)綁定,結(jié)果集映射

基礎(chǔ)支撐層

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

工作流程

  • 向SqlSession傳入SQL語句的id,以及查詢參數(shù)
  • 找到待執(zhí)行的SQL信息,交給Executor執(zhí)行器處理
  • Executor負責對SQL語句進行組裝拼接,后交給StatementHandler處理
  • StatementHandler封裝了JDBC的操作,它負責根據(jù)SQL信息,生成對應的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屬性作為唯一標識
  • 擁有namespace屬性的mapper.xml映射文件,會被注冊到Configuration中的mapperRegistry中,以便后續(xù)生成mapper代理對象
  • 一個mapper.xml,對應一個MapperBuilderAssistant對象,這個builderAssistant對象解析并保存了該mapper.xml中的公共標簽,如parameterMap,resultMap,cache,sql,這些標簽可能在某個CRUD標簽里被使用
  • 解析CRUD標簽,即 select | update | insert | delete 標簽,一個CRUD標簽,被封裝成一個MappedStatement對象,以標簽的id屬性作為唯一標識,MappedStatement里包含了SQL語句信息,參數(shù)映射信息,結(jié)果集映射信息

源碼過程

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

SQL加載與組裝過程

SQL裝載

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

源碼過程

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

SQL組裝

  • 調(diào)用Executor進行執(zhí)行時,會查找對應的MappedStatement,并調(diào)用其SqlSource的getBoundSql,進行SQL語句的組裝,并封裝查詢參數(shù)
  • 調(diào)用getBoundSql方法時,會調(diào)用SqlNode的apply方法,不同SqlNode子類,會采取不同方式,解析動態(tài)SQL標簽,并進行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中檢查是否開啟二級緩存,若開啟,則會負責二級緩存數(shù)據(jù)的存取
  • 若沒開啟二級緩存,或二級緩存沒命中,進入到BaseExecutor中,嘗試從一級緩存中拿數(shù)據(jù),若一級緩存中也沒有,則會訪問數(shù)據(jù)庫
  • 二級緩存是mapper級別的,即一個mapper,對應一個二級緩存。在源碼中,二級緩存是被MappedStatement持有。二級緩存是通過mapper映射文件中的<cache/> 標簽開啟的
  • 一級緩存無法關(guān)閉,但可以在全局配置中設置<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é)果生成一個代理對象
  • 當調(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讀取Oracle大字段數(shù)據(jù)(CLOB)的2種方法

    Java讀取Oracle大字段數(shù)據(jù)(CLOB)的2種方法

    這篇文章主要介紹了Java讀取Oracle大字段數(shù)據(jù)(CLOB)的2種方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息

    java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息

    這篇文章主要給大家介紹了關(guān)于java小知識之查詢數(shù)據(jù)庫數(shù)據(jù)的元信息,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2021-10-10
  • java實現(xiàn)登錄驗證碼功能

    java實現(xiàn)登錄驗證碼功能

    這篇文章主要為大家詳細介紹了java實現(xiàn)登錄驗證碼功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • spring boot使用sonarqube來檢查技術(shù)債務

    spring boot使用sonarqube來檢查技術(shù)債務

    今天小編就為大家分享一篇關(guān)于spring boot使用sonarqube來檢查技術(shù)債務,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 數(shù)據(jù)同步利器DataX簡介及如何使用

    數(shù)據(jù)同步利器DataX簡介及如何使用

    DataX?是阿里云?DataWorks數(shù)據(jù)集成?的開源版本,使用Java?語言編寫,在阿里巴巴集團內(nèi)被廣泛使用的離線數(shù)據(jù)同步工具/平臺,今天給大家分享一個阿里開源的數(shù)據(jù)同步工具DataX,在Github擁有14.8k的star,非常受歡迎
    2024-02-02
  • ssh框架實現(xiàn)文件上傳下載實例代碼

    ssh框架實現(xiàn)文件上傳下載實例代碼

    本篇文章主要介紹了ssh框架文件上傳下載實例代碼,實例分析了Spring+struts+Hibernate的使用技巧,非常具有實用價值,需要的朋友可以參考下。
    2017-03-03
  • JAVA Future類的使用詳解

    JAVA Future類的使用詳解

    這篇文章主要介紹了JAVA Future類的使用詳解,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下
    2021-04-04
  • springboot中實現(xiàn)上傳文件的功能簡單示例

    springboot中實現(xiàn)上傳文件的功能簡單示例

    這篇文章主要給大家介紹了關(guān)于springboot中實現(xiàn)上傳文件功能的相關(guān)資料,在Spring Boot中實現(xiàn)文件上傳下載功能相對簡單,文中給出了代碼示例,需要的朋友可以參考下
    2023-09-09
  • 解決idea 拉取代碼出現(xiàn)的 “ Сannot Run Git Cannot identify version of git executable: no response“的問題

    解決idea 拉取代碼出現(xiàn)的 “ Сannot Run Git Cannot identify version of

    這篇文章主要介紹了解決idea 拉取代碼出現(xiàn)的 “ Сannot Run Git Cannot identify version of git executable: no response“的問題,需要的朋友可以參考下
    2020-08-08
  • Java使用ArrayList實現(xiàn)撲克牌的示例代碼

    Java使用ArrayList實現(xiàn)撲克牌的示例代碼

    學習了關(guān)于集合類的知識,我們可以做一個小項目來加深對集合類知識的學習!本文就來利用ArrayList實現(xiàn)撲克牌發(fā)牌洗牌效果,需要的可以參考一下
    2022-10-10

最新評論