1. 程式人生 > 其它 >mybatis SelectKey標籤執行原理

mybatis SelectKey標籤執行原理

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;
}