上文mybatis源碼簡書我們講到sqlsession中通過executor來執行sql,我們接着往下看

這裡我們看到 clearLocalCache 方法,可見每次更新都會清除緩存
我們再看到doUpdate
1 public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
2 Statement stmt = null;
3 try {
4 Configuration configuration = ms.getConfiguration();
5 StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
6 stmt = prepareStatement(handler, ms.getStatementLog());
7 return handler.update(stmt);
8 } finally {
9 closeStatement(stmt);
10 }
11 }
先看第5行,生成一個 StatementHandler,StatementHandler是mybatis4大對象之一,負責處理Mybatis與JDBC之間Statement的互動。
我們再看下newStatementHandler,
這裡又看 RoutingStatementHandler,先不管,再點進去,會發現會有不同類型的StatementHandler
SimpleStatementHandler,這個很簡單了,就是對應我們JDBC中常用的Statement接口,用于簡單SQL的處理;
PreparedStatementHandler,這個對應JDBC中的PreparedStatement,預編譯SQL的接口;
CallableStatementHandler,這個對應JDBC中CallableStatement,用于執行存儲過程相關的接口;
RoutingStatementHandler,這個接口是以上三個接口的路由,沒有實際操作,隻是負責上面三個StatementHandler的建立及調用。
這幾個StatementHandler他有共同的構造器,都在BaseStatementHandler
1 protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
2 this.configuration = mappedStatement.getConfiguration();
3 this.executor = executor;
4 this.mappedStatement = mappedStatement;
5 this.rowBounds = rowBounds;
6
7 this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
8 this.objectFactory = configuration.getObjectFactory();
9
10 if (boundSql == null) { // issue #435, get the key before calculating the statement
11 generateKeys(parameterObject);
12 boundSql = mappedStatement.getBoundSql(parameterObject);
13 }
14
15 this.boundSql = boundSql;
16
17 this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
18 this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
19 }
這裡順便建立了parameterHandler和 resultSetHandler
parameterHandler的作用就是進行參數預編譯設定,resultSetHandler封裝我們得到的結果。
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
2 Statement stmt = null;
3 try {
4 Configuration configuration = ms.getConfiguration();
5 StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
6 stmt = prepareStatement(handler, ms.getStatementLog());
7 return handler.update(stmt);
8 } finally {
9 closeStatement(stmt);
10 }
11 }
再看第六行,我們在生成StatementHandler,開始執行prepareStatement
1 private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
2 Statement stmt;
3 Connection connection = getConnection(statementLog);
4 //調用StatementHandler.prepare
5 stmt = handler.prepare(connection);
6 //調用StatementHandler.parameterize
7 handler.parameterize(stmt);
8 return stmt;
9 }
我們看到prepare方法,生成statement,用過jdbc的都知道,Statement對象主要用于将 SQL 語句發送到資料庫中,執行對資料庫的資料的檢索或者更新
生成好statement後,我們再看下第7行
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
2 Statement stmt = null;
3 try {
4 Configuration configuration = ms.getConfiguration();
5 StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
6 stmt = prepareStatement(handler, ms.getStatementLog());
7 return handler.update(stmt);
8 } finally {
9 closeStatement(stmt);
10 }
11 }
這裡就是真正的執行sql的地方。