您的位置:

Mybatis执行器详解

一、Mybatis执行器有哪些

Mybatis执行器是Mybatis框架中的重要组成部分,用于执行SQL语句并返回结果。Mybatis执行器包括:

  • SimpleExecutor:简单执行器
  • ReuseExecutor:可重用执行器
  • BatchExecutor:批量执行器

三个执行器相互独立,也可以组合使用。

二、Mybatis三个执行器

Mybatis的三个执行器分别是SimpleExecutor、ReuseExecutor和BatchExecutor。下面对它们分别进行介绍。

1. SimpleExecutor

SimpleExecutor是Mybatis中最简单的执行器,它每次执行都会创建一个Statement对象,执行完SQL语句就立即关闭Statement对象。SimpleExecutor存在的唯一意义就是为了方便开发者从Mybatis中获取底层的JDBC执行器。SimpleExecutor主要有三个核心方法:


public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    Connection connection = getConnection(configuration);
    stmt = handlerPrepareStatement(configuration, connection, ms.getBoundSql(parameter).getSql());
    handlerParameter(stmt, ms, parameter);
    int effectCount = stmt.executeUpdate();
    return effectCount;
  } finally {
    if (stmt != null) {
      closeStmt(stmt);
    }
  }
}

public 
    List
     doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, 
    ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    Connection connection = getConnection(configuration);
    stmt = handlerPrepareStatement(configuration, connection, boundSql.getSql());
    handlerParameter(stmt, ms, parameter);
    ResultSet rs = stmt.executeQuery();
    return handlerResultSet(rs, ms, resultHandler, rowBounds, cacheKey, boundSql);
  } finally {
    if (stmt != null) {
      closeStmt(stmt);
    }
  }
}

    
   

public List
    doFlushStatements(boolean isRollback) throws SQLException {
  return null;
}

   

2. ReuseExecutor

ReuseExecutor是Mybatis中的可重用执行器,它会先从缓存中拿到Statement对象,如果缓存中没有,则创建新的Statement对象。在执行完SQL语句之后,不会立即关闭Statement对象,而是将它放回缓存中以便下次重复利用。ReuseExecutor主要有两个核心方法:


public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    Connection connection = getConnection(configuration);
    stmt = getStatement(configuration, connection, ms.getBoundSql(parameter).getSql());
    handlerParameter(stmt, ms, parameter);
    int effectCount = stmt.executeUpdate();
    return effectCount;
  } finally {
    if (stmt != null) {
      closeStmt(stmt);
    }
  }
}

public 
    List
     doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, 
    ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    Connection connection = getConnection(configuration);
    stmt = getStatement(configuration, connection, boundSql.getSql());
    handlerParameter(stmt, ms, parameter);
    ResultSet rs = stmt.executeQuery();
    return handlerResultSet(rs, ms, resultHandler, rowBounds, cacheKey, boundSql);
  } finally {
    if (stmt != null) {
      closeStmt(stmt);
    }
  }
}

    
   

3. BatchExecutor

BatchExecutor是Mybatis中的批量执行器,它采用JDBC的批量执行特性,将多个SQL语句一次性发送给数据库执行。BatchExecutor主要有三个核心方法:


public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
  addBatch(ms, parameter);
  return flushStatements();
}

public 
    List
     doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, 
    ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException {
  if (closed) {
    throw new ExecutorException("Executor was closed.");
  }
  Object cacheObject = localCache.getObject(cacheKey);
  if (cacheObject != null) {
    if (cacheObject instanceof List) {
      return resultHandler.handleResultSets(this, (List) cacheObject);
    } else if (cacheObject instanceof Cursor) {
      return resultHandler.handleCursorResultSets((Cursor) cacheObject);
    } else {
      return resultHandler.handleResultSets(this, (ResultSet) cacheObject);
    }
  }
  flushStatements();
  return null;
}

    
   

public List
    doFlushStatements(boolean isRollback) throws SQLException {
  List
     batchResults = new ArrayList
     ();
  for (Statement stmt : statementMap.values()) {
    BatchResult batchResult;
    if (isRollback) {
      batchResult = new BatchResult(stmt.getClass().getSimpleName(), new int[0], stmt.getUpdateCount());
    } else {
      batchResult = new BatchResult(stmt.getClass().getSimpleName(), stmt.executeBatch(), new int[0]);
    }
    batchResults.add(batchResult);
    closeStmt(stmt);
  }
  statementMap.clear();
  return batchResults;
}

     
    
   

三、Mybatis执行器原理

Mybatis执行器的原理是:根据用户配置的SQL,使用JDBC向数据库发送SQL请求,并接收数据库返回的结果。

Mybatis会根据用户配置的SQL类型(SELECT、UPDATE、INSERT、DELETE),来选择执行查询(Query)方法还是执行更新(Update)方法。Query方法会返回一个ResultHandler,Update方法会返回影响行数。

Mybatis中的执行器会结合JDBC提供的三种执行方式(Statement、PreparedStatement和callableStatement)和三种结果集(ResultSet、UpdateCount和ResultSetOrUpdateCount),实现对SQL语句的执行和结果的处理。

四、Mybatis执行器作用

Mybatis的执行器主要作用是抽象出常见的SQL语句,统一封装一些底层的数据库操作,从而让开发者更加便捷地操作数据库。Mybatis执行器核心就是使用JDBC向数据库发送SQL语句,并处理返回的结果。

五、Mybatis执行器类型

Mybatis执行器有三种类型:SimpleExecutor、ReuseExecutor和BatchExecutor。三个执行器相互独立,也可以组合使用。

六、Mybatis执行器有几种

Mybatis总共有三个执行器,分别是SimpleExecutor、ReuseExecutor和BatchExecutor。如上所述。

七、Mybatis执行器干什么的

Mybatis执行器主要作用是执行SQL语句并返回结果。Mybatis框架提供了不同类型的执行器,可以根据实际的需要进行选择。

八、Mybatis执行器默认

Mybatis的默认执行器是SimpleExecutor。

九、Mybatis执行流程图

Mybatis执行器的流程图如下:


                                     +-------------+
                                     | Executor    |
                                     |             |
                                     +------+------+
                                            |
      +-----------+           +--------------------+
      | Statement |-----------| StatementHandler   |
      | 或 PreparedStatement  |                    |
      +-----------+           +------+-------------+
                                       |
             +------------------------+------------------------+
             |                                                     |
     +----------+------+                                   +-----------+-------+
     | Parameter        |                                   | ResultSetHandler   |
     | Handler  |                                         |                |
     +----------+------+                                   +-----------+--------+
                                        |
                                        |
                               +-------------------+
                               | JDBC            |
                               |                  |
                               +------------------+

在执行SQL语句之前,Mybatis会将SQL语句中的参数替换成?,并将参数类型和值保存在BoundSql对象中。紧接着,Mybatis会调用StatementHandler的prepare()方法,使用JDBC的Statement对象创建SQL语句的结果集。当SQL语句中存在动态SQL时,StatementHandler会动态构建SQL语句,并将参数设置到SQL语句中。

当StatementHandler对象构建好SQL语句之后,Mybatis会将其交给JDBC驱动程序处理。当JDBC处理完SQL语句后,Mybatis会将ResultSet结果集交给ResultSetHandler进行处理。ResultSetHandler主要用来将ResultSet转化为java对象,并处理ResultSet中的异常。

最后,Mybatis会将处理结果返回给应用程序。