主要總結一下 mybaitis 的基礎配置,基本特性,最後簡單分析一下 sqlsession 的原理,了解了運行過程。
簡單配置介紹#
簡單來說,Mybatis 的配置主要分為以下幾步:
- 編寫 POJO 即 JavaBean,最終的目的是將數據庫中的查詢結果映射到 JavaBean 上;
- 配置與 POJO 對應的 Mapper 接口:裡面有各種方法,對應 mapper.xml 中的查詢語句;
- 配置與 POJO 對應的 XML 映射:編寫緩存,SQL 查詢等;
- 配置 mybatis-config.xml 主要的 Mybatis 配置文件:配置數據源、掃描 mapper.xml 等。
注意:以上的配置並沒有嚴格的前後順序;
借用一個比較清晰的配置流程圖
可以看出 mapper 接口實現類的獲得是通過 mybatis-config.xml->SqlSessionFactoryBuilder->SqlSessionFacotry->SqlSession->mapper
生命周期#
- SqlSessionFactoryBuilder:作用就是創建一個構建器,一旦創建了
SqlSessionFactory
,它的任務就算完成了,可以回收。 - SqlSessionFactory:作用是創建
SqlSession
,而SqlSession
相當於 JDBC 的一個Connection
對象,每次應用程序需要訪問數據庫,我們就要通過SqlSessionFactory
創建一個SqlSession
,所以SqlSessionFactory
在 Mybatis 整個生命周期中存在(每個數據庫對應一個SqlSessionFactory
,是單例產生的)。 - SqlSession:生命周期存在於請求數據庫處理事務的過程中,是一個線程不安全的對象(在多線程的情況下,需要特別注意),即存活於一個應用的請求和申請,可以執行多條 SQL 保證事務的一致性。
- Mapper:是一個接口,並沒有實現類。它的作用是發送 SQL,返回我們需要的結果或者發送 SQL 修改數據庫表,所以它存活於一個
SqlSession
內,是一個方法級別的東西。當SqlSession
銷毀的時候,Mapper 也會銷毀。
基礎特性#
延遲加載#
即系統延遲執行查詢,一般用於嵌套查詢的時候,嵌套在內的 SQL 查詢會延遲加載,等到真正需要使用該查詢的時候才加載。就像懶人你說一下,他動一下,絕不會多執行半步,因此該特性也稱之為懶加載。
懶加載必須配置config.xml
,並且只能通過association
或collection
實現,畢竟只有在存在映射關係的業務場景裡你需要使用懶加載
配置語句
<settings>
<setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/>
</settings>
使用時需要注意延遲加載必須使用 resultMap,resultType 不具有延遲加載功能。
一級緩存#
- 系統默認開啟,緩存的範圍為一個
SqlSession
- 只有一個 SqlSession 下的相同查詢才會應用緩存,不同 sqlSession 下的即使查詢相同一級緩存也不會生效
二級緩存#
-
解決
SqlSession
相互隔離的情況,緩存範圍為一個Mapper
接口 -
二級緩存默認是不開啟的,需要進行配置,Mybatis 要求返回的 POJO 必須是可序列化的,即 POJO 實現 Serializable 接口。
-
緩存的配置只需要在
XML
配置<cache/>
即可,或者指定算法,刷新時間間隔,緩存狀態,大小等例:
- 映射語句文件中所有 select 語句將會被緩存;
- 映射語句文件中所有 insert、update 和 delete 語句會被刷新緩存;
- 緩存使用默認的 LRU 最近最少使用算法回收;
- 根據時間表,緩存不會任何時間順序刷新
- 緩存會存儲列表集合或對象的 1024 個引用
- 緩存被視為可 read/write 的緩存,意味著是不可以被共享的,而可以被安全地修改。
自定義緩存#
通過 Mybatis 實現的接口,使用 redis 等進行緩存
實踐配置#
待補充
SqlSession 原理#
SqlSession
提供 select/insert/update/delete 方法
映射器(Mapper
)其實就是一個動態代理對象,進入到MapperMethod
的execute
方法就能簡單找到SqlSession
的刪除、更新、查詢、選擇方法.
從底層實現來說:通過動態代理技術,讓接口跑起來,之後采用命令模式,最後還是采用了SqlSession
的接口方法(getMapper()
方法等到Mapper
)執行 SQL 查詢(也就是說 Mapper 接口方法的實現底層還是采用SqlSession
接口方法實現的)。
SqlSession 重要的四個對象
- Execute:調度執行
StatementHandler
、ParmmeterHandler
、ResultHandler
執行相應的 SQL 語句; - StatementHandler:使用數據庫中
Statement(PrepareStatement)
執行操作,即底層是封裝好了的prepareStatement
- ParammeterHandler:處理 SQL 參數
- ResultHandler:結果集 ResultSet 封裝處理返回。
SqlSession 的四大對象#
Execute#
起 java 和數據庫交互橋樑的作用,參與整個 SQL 執行過程。分類
- SIMPLE 簡易執行器(默認)
- REUSE 重用預處理執行器
- BATCH 批量更新、批量專用處理器
源碼
package org.apache.ibatis.session;
public enum ExecutorType { SIMPLE, REUSE, BATCH}
作用
調度其他對象,完成預編譯、配置參數和返回結果集
StatementHanlde#
分類(分別對應不同執行器)
- SimpleStatementHandler
- PrepareStatementHandler
- CallableStatementHandler
作用
專門處理數據庫會話。進行預編譯並調用 ParameterHandler 配置參數。大致來講只是對數據庫的連接做了封裝
工作流程
- 通過調用RoutingStatementHandler對象生成 StatemenetHandler
- RoutingStatementHandler 查找相應的 statementHandler 對象
- statementHandler 調用數據庫的方法
ParameterHandler#
作用
對預編譯的參數進行設置
工作流程
- 從 parameterObject 中取到參數,然後使用 typeHandler(註冊在 Configuration 中)進行參數處理
ResultSetHandler#
作用
組裝結果返回結果集
運行過程總結#
- prepare 預編譯
- parameterize 設置參數
- doUpdate/doQuery 執行 SQL
神人的總結
參考鏈接