簡介
MyBatis是一個輕量級的ORM框架,它簡化了對關系數據庫的使用,開發人員可以在XML或注解中編寫SQL來完成對數據庫的操作。
如果完全使用XML方式,SQL語句可以集中維護,做到與Java代碼完全隔離,便于對SQL調優。
原理和流程
1 加載配置:配置來源于兩個地方,一是配置文件,一是Java代碼的注解,將SQL的配置信息加載成為一個個MappedStatement對象(包括了傳入參數映射配置、執行的SQL語句、結果映射配置),存儲在內存中。
2 SQL解析:當API接口層接收到調用請求時,會接收到傳入SQL的ID和傳入對象(可以是Map、JavaBean或者基本數據類型),Mybatis會根據SQL的ID找到對應的MappedStatement,然后根據傳入參數對象對MappedStatement進行解析,解析后可以得到最終要執行的SQL語句和參數。
3 SQL執行:將最終得到的SQL和參數拿到數據庫進行執行,得到操作數據庫的結果。
4 結果映射:將操作數據庫的結果按照映射的配置進行轉換,可以轉換成HashMap、JavaBean或者基本數據類型,并將最終結果返回。
反射和動態代理
解析是將SQL或存儲過程定義表述為Mybatis中對應對象的過程,例如將執行的Sql標簽( , …)解析為 MappedStatement ;輸入參數定義標簽解析為 ParameterMap ;結果列定義標簽解析為 ResultMap。
Mybatis支持將一個類的方法映射到一個 mapper 文件里的對應 statement sql,將方法名與DML SQL標簽的id對應起來,這樣我們就可以透明地使用 interface 的方式結合了面向對象的方式來與數據庫操作,這樣做更趨近于面向對象的編程風格。其中用到jdbc動態代理原理,用 MapperProxy 動態代理了需要執行的接口方法,主要代理邏輯在 MapperMethod 中實現,負責用接口的名稱以及方法名稱找到解析好的 MappedStatement 然后調用 SqlSession 中對應的執行邏輯執行。
緩存
Mybatis的一級緩存是SqlSession級別。第一次執行select時候會發現sqlsession緩存沒有記錄,會去數據庫查找,然后把結果保存到緩存,第二次同等條件查詢下,就會從緩存中查找到結果。另外為了避免臟讀,每次執行更新新增刪除時候會清空當前sqlsession緩存。
二級緩存是namespace級別的。同一個namespace下的搜尋語句共享一個二級緩存。如果開啟了二級緩存,則先從二級緩存中查找,查找不到則委托為SimpleExecutor查找,而它則會先從一級緩存中查找,查找不到則從數據庫查找。
mybaits的二級緩存一般不怎么使用,默認一級緩存是開啟的。
MyBatis的主要成員
- Configuration MyBatis所有的配置信息都保存在Configuration對象之中,配置文件中的大部分配置都會存儲到該類中
- SqlSession 作為MyBatis工作的主要頂層API,表示和數據庫交互時的會話,完成必要數據庫增刪改查功能
- Executor MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護
- StatementHandler 封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設置參數等
- ParameterHandler 負責對用戶傳遞的參數轉換成JDBC Statement 所對應的數據類型
- ResultSetHandler 負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合
- TypeHandler 負責java數據類型和jdbc數據類型(也可以說是數據表列類型)之間的映射和轉換
- MappedStatement MappedStatement維護一條<select|update|delete|insert>節點的封裝
- SqlSource 負責根據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,并返回
-
BoundSql 表示動態生成的SQL語句以及相應的參數信息
以上主要成員在一次數據庫操作中基本都會涉及,在SQL操作中重點需要關注的是SQL參數什么時候被設置和結果集怎么轉換為JavaBean對象的,這兩個過程正好對應StatementHandler和ResultSetHandler類中的處理邏輯。
無標題.png