文章目錄
Pre
如果MyBatis的基礎用法還不熟悉,31篇入門博客拿走不謝
戳戳戳 —> https://blog.csdn.net/yangshangwei/category_7205317.html
JDBC的執行過程
MyBatis 半自動的ORM框架 ,歸根到底底層還是用的JDBC來訪問數據庫 , 所以有必要先回顧一下JDBC的執行過程
JDBC Demo
【演示Table 】
【演示Code】
public class JdbcTest {
public static final String URL = "jdbc:mysql://127.0.0.1:3306/o2o?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8&useSSL=false";
public static final String USERNAME = "root";
public static final String PASSWORD = "root";
private Connection connection;
@Before
public void init() throws SQLException {
// 第一步 獲取連接
connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
}
@After
public void over() throws SQLException {
connection.close();
}
@Test
public void jdbcTest() throws SQLException {
// 第二步 預編譯 & 設置參數
String sql = "SELECT * FROM tb_area WHERE `area_name`=?";
PreparedStatement sql1 = connection.prepareStatement(sql);
sql1.setString(1,"北京");
// 第三步 執行SQL
sql1.execute();
// 第四步 獲取返回結果
ResultSet resultSet = sql1.getResultSet();
while (resultSet.next()) {
System.out.println(resultSet.getString(3));
}
resultSet.close();
sql1.close();;
}
}
【執行結果】
【JDBC執行步驟總結】
無非就是下面幾步
- 獲取連接
- 預處理SQL ,設置參數等
- 執行SQL
- 獲取返回結果
Mybatis既然是JDBC的封裝框架, 那自然要處理 預處理這一步 ,所以有必要了解下JDBC中的Statement 接口
JDBC Statement 接口
整體接口和類的關係圖如下
這裏重點說一下 Statement 接口 ,通過該組件來發送對應的SQL與參數 .
它有三種類型:分別是 Statement,PreparedStatement和CallableStatement 接口, 繼承關係如上,
【Statement接口】
普通的不帶參的查詢SQL
支持批量更新,批量刪除
【PreparedStatement接口】
繼承自Statement接口
可變參數的SQL,編譯一次,執行多次,效率高
安全,有效防止Sql注入等問題
支持批量更新,批量刪除
【CallableStatement接口】
繼承自PreparedStatement接口
支持帶參數的SQL操作
支持調用存儲過程,提供了對輸出和輸入/輸出參數(INOUT)的支持
除了常見的接口方法, Statement 中還有2個非常規方法需要關注下,因爲後續在MyBatis中源碼會有體現。
-
addBatch: 批處理操作,將多個SQL合併在一起,最後調用executeBatch 一起發送至數據庫執行
-
setFetchSize:設置從數據庫每次讀取的數量單位。該舉措是爲了防止一次性從數據庫加載數據過多,導致內存溢出。(MySQL不支持 ,Oracle支持)
MyBatis執行過程
推薦使用魯班大叔的源碼地圖來梳理MyBatis的源碼執行過程,更直觀易懂 。 ------->戳這裏<----------
四大組件
每個組件的作用如下:
-
接口代理: 其目的是簡化對MyBatis使用,底層使用動態代理實現
-
Sql會話: 提供增刪改查API,其本身不作任何業務邏輯的處理,所有處理都交給執行器。這是一個典型的門面設計模式
-
執行器: 核心作用是處理SQL請求、事物管理、維護緩存以及批處理等 。執行器在的角色更像是一個管理員,接收SQL請求,然後根據緩存、批處理等邏輯來決定如何執行這個SQL請求,並交給JDBC處理器執行具體SQL
-
JDBC處理器:他的作用就是用於通過JDBC具體處理SQL和參數的。在會話中每調用一次CRUD,JDBC處理器就會生成一個實例與之對應(命中緩存除外)
請注意在一次SQL會話過程當中四個組件的實例比值分別是 1:1:1:n
組件之間的關係
一個SQL請求通過會話到達執行器,然後交給對應的JDBC處理器進行處理。
另外所有的組件都不是線程安全的,不能跨線程使用 (currentSql 全局變量 ,線程不安全 )
接下來我們重點看下Executor組件,從源碼上剖析該組件的設計思想。
Executor 執行器組件
架構總覽
Executor是MyBatis執行者接口 ,執行器的主要功能包括:
-
基本功能:改、查,(增刪—>也是改)
-
緩存維護:這裏的緩存主要是爲一級緩存服務,功能包括創建緩存Key、清理緩存、判斷緩存是否存在
-
事務管理:提交、回滾、關閉、批處理刷新
接口繼承關係
我們重點看下Executor的 三個實現子類。
分別是:SimpleExecutor(簡單執行器)、ReuseExecutor(重用執行器)、BatchExecutor(批處理執行器)。