mybatis SelectKey標籤執行原理
阿新 • • 發佈:2022-11-29
SelectKey標籤在mybatis中可以配置成在主sql執行之前和執行之後兩種時機進行執行。
mybatis執行sql時一次會涉及到這些物件
sqlSession
-->Executor
-->StatementHandler
其中selectKey的處理就是在StatementHandler中進行的
一、在主sql執行之前執行
在BaseStatementHandler
的構造方法中會檢查是否需要處理selectKey的執行,這就是在主sql執行之前執行
protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { this.configuration = mappedStatement.getConfiguration(); this.executor = executor; this.mappedStatement = mappedStatement; this.rowBounds = rowBounds; this.typeHandlerRegistry = configuration.getTypeHandlerRegistry(); this.objectFactory = configuration.getObjectFactory(); if (boundSql == null) { //這塊就是在處理主sql之前執行selectKey generateKeys(parameterObject); boundSql = mappedStatement.getBoundSql(parameterObject); } this.boundSql = boundSql; this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql); this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql); } protected void generateKeys(Object parameter) { KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); ErrorContext.instance().store(); //這塊是具體的方法,keyGenerator是一個介面,當使用selectKey標籤時,對應的實現類是 // SelectKeyGenerator keyGenerator.processBefore(executor, mappedStatement, null, parameter); ErrorContext.instance().recall(); }
二、在主sql執行之後執行
StatementHandler是一個介面,BaseStatementHandler是一個公共實現類,具體的資料庫處理邏輯是在其子類中實現的。我們以PreparedStatementHandler
舉例,insert語句最終會通過statementHandler中的 update方法來執行
public int update(Statement statement) throws SQLException { PreparedStatement ps = (PreparedStatement) statement; //這裡是用PreparedStatement執行sql語句 ps.execute(); int rows = ps.getUpdateCount(); Object parameterObject = boundSql.getParameterObject(); KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); // 這裡就是在處理主sql之後執行selectKey標籤 keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject); return rows; }