国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術文章
文章詳情頁

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

瀏覽:2日期:2022-08-09 18:29:00
目錄持久層的那些事什么是 JDBCJDBC 原理什么是 MybatisMybatis 與 JDBC 的關系SqlSessionSqlSessionFactorySqlSessionFactoryBuilderConfigurationMappedStatementExecutorParameterHandlerStatementHandlerResultSetHandlerInterceptorMybatis 關鍵詞說明Mybatis 架構設計基礎支持層反射模塊類型轉換日志模塊資源加載解析器模塊核心處理層問題答疑Mybatis 中分頁如何實現SQL 分頁攔截器分頁總結持久層的那些事什么是 JDBC

JDBC(JavaDataBase Connectivity)就是 Java 數據庫連接, 說的直白點就是 使用 Java 語言操作數據庫

本來我們是通過控制臺或客戶端操作的數據庫, JDBC 是用 Java 語言來發送 SQL 語句

JDBC 原理

最初 SUN 公司希望提供一套 能夠適用所有數據庫的 API, 但是在實際操作中卻發現這是項基本不可能完成的任務

因為各個廠商所提供的 數據庫差異實在太大, 所以 SUN 公司與數據庫廠商討論出的就是:由 SUN 公司提供出一套訪問數據庫的規范 API, 并提供相對應的連接數據庫協議標準, 然后各廠商根據規范提供一套訪問自家數據庫的 API 接口

最終:SUN 公司提供的規范 API 稱之為 JDBC, 各廠商提供的自家數據庫 API 接口稱之為 驅動

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

什么是 Mybatis

Mybatis 是一款優秀的 ORM(持久層)框架,使用 Java 語言 編寫前身是 apache 的一個開源項目 iBatis,2010 年遷移到 google code 并正式改名為 Mybatis ORM 持久層 指的是 : 將業務數據存儲到磁盤,也具備長期存儲能力,只要磁盤不損壞,如果在斷電情況下,重啟系統仍然可以讀取數據

Mybatis 與 JDBC 的關系

在沒有持久層框架之前, 想要代碼中操作數據庫都必須通過 JDBC 來操作, 接下來一個例子來說明兩者之間的關系

JDBC 操作數據庫

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

相信大家都在實際項目中使用過 Mybatis, 可以聯想一下, 平常我們工作中, 是否做過以下事情:

是否裝載過數據庫驅動? 是否從驅動中獲取數據庫連接? 是否創建過執行 SQL 的 Statement? 是否自行將數據庫返回結果轉換成 Java 對象? 是否關閉過 finally 塊中的三個對象?

看到上面的靈魂拷問, 就可以對本次分享的第一個問題作出解答:

Mybatis 針對 JDBC 中重復操作做了封裝, 同時擴展并優化部分功能

Mybatis 關鍵詞說明

📖 如果在閱讀文章前沒有接觸過 Mybatis 源碼相關的內容, 建議將下述名詞多看幾遍再向下閱讀

SqlSession

負責執行 select、insert、update、delete 等命令, 同時負責獲取映射器和管理事務; 其底層封裝了與 JDBC 的交互, 可以說是 mybatis 最核心的接口之一

SqlSessionFactory

負責創建 SqlSession 的工廠, 一旦被創建就應該在應用運行期間一直存在, 不需要額外再進行創建

SqlSessionFactoryBuilder

主要是負責創建 SqlSessionFactory 的構造器類, 其中使用到了構建者設計模式; 僅負責創建 SqlSessionFactory

Configuration

Mybatis 最重要的配置類, 沒有之一, 存儲了大量的對象配置, 可以看源碼感受一下

MappedStatement

MappedStatement 是保存 SQL 語句的數據結構, 其中的類屬性都是由解析 .xml 文件中的 SQL 標簽轉化而成

Executor

SqlSession 對象對應一個 Executor, Executor 對象作用于 增刪改查方法 以及 事務、緩存 等操作

ParameterHandler

Mybatis 中的 參數處理器, 類關系比較簡單

StatementHandler

StatementHandler 是 Mybatis 負責 創建 Statement 的處理器, 根據不同的業務創建不同功能的 Statement

ResultSetHandler

ResultSetHandler 是 Mybatis 負責將 JDBC 返回數據進行解析, 并包裝為 Java 中對應數據結構的處理器

Interceptor

Interceptor 為 Mybatis 中定義公共攔截器的接口, 其中定義了相關實現方法

Mybatis 架構設計

架構圖

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

基礎支持層反射模塊

反射在 Java 中的應用可以說是相當廣泛了, 同時也是一把雙刃劍。 Mybatis 框架本身 封裝出了反射模塊, 提供了比原生反射更 簡潔易用的 API 接口, 以及對 類的元數據增加緩存, 提高反射的性能

類型轉換

類型轉換模塊最重要的功能就是在為 SQL 語句綁定實參時, 將 Java 類型轉為 JDBC 類型, 在映射結果集時再由 JDBC 類型轉為 Java 類型

另外一個功能就是提供別名機制, 簡化了配置文件的定義

日志模塊

日志對于系統的作用不言而喻, 尤其是測試、生產環境上查看信息及排查錯誤等都非常重要。主流的日志框架包括 Log4j、Log4j2、S l f4j 等, Mybatis 的日志模塊作用就是 集成這些日志框架

資源加載

Mybatis 對類加載器進行了封裝, 用來確定類加載器的使用順序, 用來記載類文件以及其它資源文件, 感興趣可以參考 ClassLoaderWrapper

解析器模塊

解析器模塊主要提供了兩個功能, 一個是封裝了 XPath 類, 在 Mybatis 初始化時解析 Mybatis-config.xml 配置文件以及映射配置文件提供功能, 另一點就是處理動態 SQL 語句的占位符提供幫助

核心處理層

配置解析

在 Mybatis 初始化時, 會加載 Mybatis-config.xml 文件中的配置信息, 解析后的配置信息會 轉換成 Java 對象添加到 Configuration 對象

📖 比如說在 .xml 中定義的 resultMap 標簽, 會被解析為 ResultMap 對象

SQL 解析

大家如果手動拼寫過復雜 SQL 語句, 就會明白會有多痛苦。Mybatis 提供出了動態 SQL, 加入了許多判斷循環型標簽, 比如 : if、where、foreach、set 等, 幫助開發者節約了大量的 SQL 拼寫時間 SQL 解析模塊的作用就是將 Mybatis 提供的動態 SQL 標簽解析為帶占位符的 SQL 語句, 并在后期將實參對占位符進行替換

SQL 執行

SQL 的執行過程涉及幾個比較重要的對象, Executor、StatementHandler、ParameterHandler、ResultSetHandler

Executor負責維護 一級、二級緩存以及事務提交回滾操作, 舉個查詢的例子, 查詢請求會由 Executor 交給 StatementHandler 完成

StatementHandler 通過ParameterHandler完成SQL語句的實參綁定, 通過java.sql.Statement執行 SQL語句并拿到對應的 結果集映射

最后交由 ResultSetHandler 對結果集進行解析, 將 JDBC 類型轉換為程序自定義的對象

插件

插件模塊是 Mybatis 提供的一層擴展, 可以針對 SQL 執行的四大對象進行 攔截并執行自定義插件插件編寫需要很熟悉 Mybatis 運行機制, 這樣才能控制編寫的插件安全、高效

接口層

接口層只是 Mybatis 提供給調用端的一個接口 SqlSession, 調用端在進行調用接口中方法時, 會調用核心處理層相對應的模塊來完成數據庫操作

問題答疑

.xml 文件定義 Sql 語句如何解析

Mybatis 在創建 SqlSessionFactory 時, XMLConfigBuilder 會解析 Mybatis-config.xml 配置文件

Mybatis 相關解析器

Mybatis 解析器模塊中定義了相關解析器的抽象類 BaseBuilder, 不同的子類負責實現解析不同的功能, 使用了 Builder 設計模式

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

XMLConfigBuilder 負責解析 mybatis-config.xml 配置文件

XMLMapperBuilder 負責解析業務產生的 xxxMapper.xml

mybatis-config.xml 解析

XMLConfigBuilder 解析 mybatis-config.xml 內容參考代碼 :

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

XMLConfifigBuilder#parseConfiguration()方法將 mybatis-config.xml中定義的標簽進行相關解析并填充到Configuration對象中

xxxMapper.xml 解析

XMLConfifigBuilder#mapperElement()中解析配置的 mappers 標簽, 找到具體的.xml文件, 并將其中的select、insert、update、delete、resultMap 等標簽解析為 Java 中的對象信息具體解析 xxxMapper.xml 的對象為 XMLMapperBuilder, 具體的解析方法為parse()

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

Mybatis創建 SqlSessionFactory 會解析mybatis-config.xml, 然后 解析configuration 標簽下的子標簽, 解析 mappers 標簽時, 會根據相關配置讀取到 .xml 文件, 繼而解析 .xml中各個標簽具體的 select、insert、update、delete 標簽定義為 MappedStatement對象, .xml文件中的其余標簽也會根據不同映射解析為 Java 對象

MappedStatement

這里重點說明下 MappedStatement 對象, 一起看一下類中的屬性和 SQL 有何關聯呢

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

MappedStatement 對象中 提供的屬性與 .xml 文件中定義的 SQL 語句 是能夠對應上的, 用來 控制每條 SQL 語句的執行行為

Mapper 接口的存儲與實現

在平常我們寫的 SSM 框架中, 定義了 Mapper 接口與 .xml 對應的 SQL 文件, 在 Service 層直接注入 xxxMapper 就可以了

也沒有看到像 JDBC 操作數據庫的操作, Mybatis 在中間是如何為我們省略下這些重復繁瑣的操作呢

這里使用 Mybatis 源碼中的測試類進行驗證, 首先定義 Mapper 接口, 省事直接注解定義 SQL

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

這里使用 SqlSession 來獲取 Mapper 操作數據庫, 測試方法如下

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

創建 SqlSession

#1 從 SqlSessionFactory 中打開一個 新的 SqlSession

獲取 Mapper 實例

#2 就存在一個疑問點, 定義的 AutoConstructorMapper 明明是個接口, 為什么可以實例化為對象?

動態代理方法調用

#3 通過創建的對象調用類中具體的方法, 這里具體聊一下 #2 操作

SqlSession 是一個接口, 有一個 默認的實現類 DefaultSqlSession, 類中包含了 Configuration 屬性

Mapper 接口的信息以及 .xml 中SQL語句是在Mybatis初始化時添加 到 Configuration 的 MapperRegistry 屬性中的

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

#2中的 getMapper 就是從 MapperRegistry 中獲取 Mapper

看一下 MapperRegistry 的類屬性都有什么

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

config 為 保持全局唯一 的 Configuration 對象引用

knownMappers 中 Key-Class 是 Mapper 對象, Value-MapperProxyFactory 是通過 Mapper 對象衍生出的 Mapper 代理工廠

再看一下 MapperProxyFactory 類的結構信息

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

mapperInterface 屬性是 Mapper 對象的引用, methodCache 的 key 是 Mapper 中的方法, value 是 Mapper 解析對應 SQL 產生的 MapperMethod

📖 Mybatis 設計 methodCache 屬性時使用到了 懶加載機制, 在初始化時不會增加對應 Method, 而是在 第一次調用時新增

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

MapperMethod 運行時數據如下, 比較容易理解

通過一個實際例子幫忙理解一下 MapperRegistry 類關系, Mapper 初始化第一次調用的對象狀態, 可以看到 methodCache 容量為0

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

我們目前已經知道 MapperRegistry的類關系, 回頭繼續看一下第二步的 MapperRegistry#getMapper() 處理步驟

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

核心處理在 MapperProxyFactory#newInstance()方法中, 繼續跟進

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

MapperProxy繼承了 InvocationHandler 接口, 通過 newInstance() 最終返回的是由 Java Proxy 動態代理返回的動態代理實現類

看到這里就清楚了步驟二中接口為什么能夠被實例化, 返回的是 接口的動態代理實現類

Mybatis Sql 的執行過程

根據 Mybatis SQL 執行流程圖進一步了解

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

大致可以分為以下幾步操作:

📖 在前面的內容中, 知道了Mybatis Mapper 是動態代理的實現, 查看 SQL 執行過程, 就需要緊跟實現InvocationHandler 的MapperProxy類

執行增刪改查

@Select(' SELECT * FROM SUBJECT WHERE ID = #{id}')PrimitiveSubject getSubject(@Param('id') final int id);

我們以上述方法舉例, 調用方通過 SqlSession 獲取Mapper動態代理對象, 執行Mapper方法時會通過InvocationHandler進行代理

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

在MapperMethod#execute 中, 根據 MapperMethod -> SqlCommand -> SqlCommandType 來確定增、刪、改、查方法

📖 SqlCommandType 是一個枚舉類型, 對應五種類型 UNKNOWN、INSERT、UPDATE、DELETE、SELECT、FLUSH

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

參數處理

查詢操作對應 SELECT 枚舉值, if else 中判斷為返回值是否集合、無返回值、單條查詢等, 這里以查詢單條記錄作為入口

Object param = method.convertArgsToSqlCommandParam(args);result = sqlSession.selectOne(command.getName(), param);

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

📖 這里能夠解釋一個之前困擾我的問題, 那就是為什么方法入參只有單個 @Param('id'), 但是參數 param 對象會存在兩個鍵值對

繼續查看 SqlSession#selectOne 方法, sqlSession 是一個接口, 具體還是要看實現類 DefaultSqlSession

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

因為單條和查詢多條以及分頁查詢都是走的一個方法, 所以在查詢的過程中, 會將分頁的參數進行添加

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

執行器處理

在 Mybatis 源碼中, 創建的執行器默認是 CachingExecutor, 使用了裝飾者模式, 在類中保持了 Executor 接口的引用, CachingExecutor 在持有的執行器基礎上增加了緩存的功能

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

delegate.query 就是在具體的執行器了, 默認 SimpleExecutor, query 方法統一在抽象父類 BaseExecutor 中維護

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

BaseExecutor#queryFromDatabase 方法執行了緩存占位符以及執行具體方法, 并將查詢返回數據添加至緩存

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

BaseExecutor#doQuery 方法是由具體的 SimpleExecutor 實現

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

執行 SQL

因為我們 SQL 中使用了參數占位符, 使用的是 PreparedStatementHandler 對象, 執行預編譯SQL的 Handler, 實際使用 PreparedStatement 進行 SQL 調用

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

返回數據解析

將 JDBC 返回類型轉換為 Java 類型, 根據 resultSets 和 resultMap 進行轉換

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

Mybatis 中分頁如何實現

通過 Mybatis 執行分頁 SQL 有兩種實現方式, 一種是編寫 SQL 時添加 LIMIT, 一種是全局處理

SQL 分頁

<select resultMap='resultAutoMap'> SELECT * FROM SUBJECT LIMIT #{CURRINDEX} , #{PAGESIZE}</select>攔截器分頁

上文說到, Mybatis 支持了插件擴展機制, 可以攔截到具體對象的方法以及對應入參級別

我們添加插件時需要實現Interceptor 接口, 然后將插件寫在 mybatis-config.xml 配置文件中或者添加相關注解, Mybatis 初始化時解析才能在項目啟動時添加到插件容器中

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

由一個 List 結構存儲項目中全部攔截器, 通過Configuration#addInterceptor 方法添加

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

重點需要關注 Interceptor#pluginAll 中 plugin 方法, Interceptor 只是一個接口, plugin 方法只能由其實現類完成

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

Plugin 可以理解為是一個工具類, Plugin#wrap 返回的是一個動態代理類

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

這里使用一個測試的 Demo 看一下方法運行時的參數

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

雖然是隨便寫的 Demo, 但是與正式使用的插件并無實際區別

一篇文章告訴你JAVA Mybatis框架的核心原理到底有多重要

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注好吧啦網的更多內容!

標簽: Java
相關文章:
主站蜘蛛池模板: 久久精品视频一区 | 欧美综合另类 | 国产婷婷一区二区在线观看 | 欧美国产在线视频 | 99久久成人国产精品免费 | 亚洲成人第一 | 欧美精品成人一区二区视频一 | 亚洲一片| 456亚洲老头视频 | 91大神在线精品视频一区 | 最新国产成人综合在线观看 | 91热视频在线观看 | 免费观看性欧美毛片 | 国产成人精品综合在线观看 | 日韩无砖专区体验区 | 国产初高中生粉嫩无套第一次 | av毛片免费看 | 国产一级一级一级成人毛片 | 欧美三级三级三级爽爽爽 | 一级片国产 | 韩国精品一区视频在线播放 | 欧美怡红院免费的视频 | 欧美久久一区二区 | 亚洲精品91香蕉综合区 | 国产一级性生活 | 男人操女人逼逼视频 | 国产一及片 | 免费五级在线观看日本片 | 亚洲网视频 | 亚洲日本韩国在线 | 国产午夜毛片v一区二区三区 | 窝窝午夜看片七次郎青草视频 | 久草视频福利资源站 | a级毛片在线免费看 | 日韩美女在线视频 | 九九视频精品在线 | 1024手机基地在线看手机 | 欧美一级欧美三级在线观看 | 亚洲精品久久久久久久久久久网站 | 成人免费毛片观看 | 午夜三级在线观看 |