mybatis源碼解讀之executor包語句處理功能

1.mybatis對多語句類型的支持

mybatis映射文件中傳參數,主要用到#{} 或者 ${}.

#{}:表示使用這種符號的變量會以預編譯的形式賦值到sql片段中。

${}:表示使用這種符號的變量會以字符串的形式直接插到sql片段中。

mybatis中支持三種語句類型,不同語句類型支持的變量符號不同。mybatis的三種類型如下:

  • STATEMENT:這種語句類型中,隻會對sql片段進行簡單的字符串拼接。隻支持使用${}.
  • PREPARED:這種語句中會先對sql片段進行字符串拼接,然後再對sql片段進行賦值。可以使用#{}和${}.
  • CALLABLE:這種語句用瞭實現執行過程的調用,會先對sql片段進行字符串拼接,然後對sql片段進行賦值。可以使用#{}和${}.

2.mybatis的語句處理功能

statement子包負責提供語句處理功能,其中StatementHandler是語句功能類的父接口,RoutingStatementHandler類是一個代理類,它能夠根據傳入的MappedStatement對象的具體類型選中一個具體的被代理對象,然後將所有實際操作都委托給被代理對象。所以RoutingStatementHandler類提供的是路由功能,而路由選擇的依據就是語句類型。

public class RoutingStatementHandler implements StatementHandler {

  // 根據語句類型選取出的被代理類的對象
  private final StatementHandler delegate;

  public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    // 根據語句類型選擇被代理對象
    switch (ms.getStatementType()) {
      case STATEMENT:
        delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      case PREPARED:
        delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      case CALLABLE:
        delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
        break;
      default:
        throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
    }
  }
}

BaseStatementHandler作為三個實現類的父類,提供瞭實現類的公共方法。並且BaseStatementHandler類使用的模板模式在prepare方法中定義瞭整個方法的框架,然後將一些與子類相關的操作交給三個子類處理。

SimpleStatementHandler類、PreparedStatementHandler類和CallableStatementHandler類是三個真正的statement處理器,分別處理statement、preparedStatementCallableStatement對象。通過其中的parameterize方法可以看出三個Statement處理器的不同。

SimpleStatementHandlerparameterize方法的實現為空,因為它隻需要完成字符串替換即可,不需要進行參數處理

public class SimpleStatementHandler extends BaseStatementHandler {

 @Override
  public void parameterize(Statement statement) {
    // N/A
  }

  }

PreparedStatementHandlerparameterize方法最終通過ParameterHandler接口經過多級中轉後調用瞭PreparedStatement類中的參數賦值方法。

public class PreparedStatementHandler extends BaseStatementHandler {
  @Override
  public void parameterize(Statement statement) throws SQLException {
    parameterHandler.setParameters((PreparedStatement) statement);
  }
}

CallableStatementHandler中parameterize主要是通過registerOutputParameters方法中轉後調用CallableStatement中的輸出參數註冊方法完成輸出參數的註冊,然後通過ParameterHandler接口經過多級中轉後調用瞭PreparedStatement類中的參數賦值方法。

public class CallableStatementHandler extends BaseStatementHandler {
 /**
   * 對語句進行參數處理
   * @param statement SQL語句
   * @throws SQLException
   */
  @Override
  public void parameterize(Statement statement) throws SQLException {
    // 輸出參數的註冊
    registerOutputParameters((CallableStatement) statement);
    // 輸入參數的處理
    parameterHandler.setParameters((CallableStatement) statement);
  }

}

到此這篇關於  mybatis源碼解讀之executor包語句處理功能的文章就介紹到這瞭,更多相關executor包語句處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: