mybatis 有哪些执行器(Executor)?

MyBatis的Executor有三种类型:SimpleExecutor每次执行都创建新Statement,适合低频操作;ReuseExecutor复用Statement提升性能,适用于相同SQL频繁执行;BatchExecutor批量处理更新操作,适用于大量写入场景。选择依据应用场景和性能需求,可通过配置文件设置defaultExecutorType指定类型。

MyBatis 的执行器(Executor)负责执行 SQL 查询并处理结果。简单来说,它们是 MyBatis 连接数据库并返回数据的核心组件。不同的执行器类型在性能和功能上有所差异,允许开发者根据应用场景进行选择。

Executor 分为三种主要类型:SimpleExecutor、ReuseExecutor 和 BatchExecutor。

SimpleExecutor:简单直接的执行方式

SimpleExecutor 是 MyBatis 默认的执行器。它的工作方式非常直接:每次执行 update 或 select 操作时,都会创建一个新的 Statement 对象。执行完毕后,Statement 对象会被立即关闭。这种方式简单易懂,易于调试,但效率相对较低,因为频繁创建和销毁 Statement 对象会带来一定的开销。

想象一下,你每次去咖啡馆点一杯咖啡,咖啡师都必须拿出全新的咖啡机和杯子,用完就扔掉。虽然干净卫生,但很浪费时间。SimpleExecutor 就有点像这个场景。

ReuseExecutor:Statement 对象的复用

ReuseExecutor 旨在通过复用 Statement 对象来提高性能。在同一个会话中,如果执行的 SQL 语句相同(仅参数不同),ReuseExecutor 会尝试使用之前创建的 Statement 对象,而不是每次都创建新的。这样可以减少 Statement 对象的创建和销毁次数,从而提升效率。

还是咖啡馆的例子,ReuseExecutor 就像咖啡师会保留常用的咖啡机和杯子,只要清洗干净就可以重复使用,不用每次都换新的。

但是,需要注意的是,ReuseExecutor 的复用是基于 SQL 语句的完全匹配。如果 SQL 语句稍有不同(例如,不同的列名或条件),ReuseExecutor 仍然会创建新的 Statement 对象。此外,当事务提交或回滚时,所有 Statement 对象都会被关闭。

BatchExecutor:批量处理,提升效率

BatchExecutor 适用于需要执行大量更新操作的场景。它会将多个 SQL 语句收集起来,然后一次性提交给数据库执行。这样可以减少与数据库的交互次数,从而显著提高效率。

可以把 BatchExecutor 想象成一个打包员,他不是收到一个包裹就立即发货,而是把多个包裹收集起来,然后一起发货。这样可以节省运输成本。

使用 BatchExecutor 时,需要注意以下几点:

  • 需要手动调用 Executor.flushStatements() 方法来强制执行批量操作。
  • 数据库驱动程序必须支持批量操作。
  • 批量操作的结果返回顺序可能与 SQL 语句的执行顺序不一致。

如何选择合适的 Executor?

选择哪种 Executor 取决于具体的应用场景。

  • 如果应用对性能要求不高,或者 SQL 语句的执行次数不多,可以选择 SimpleExecutor。
  • 如果应用需要频繁执行相同的 SQL 语句,可以选择 ReuseExecutor。
  • 如果应用需要执行大量的更新操作,可以选择 BatchExecutor。

此外,还可以通过 MyBatis 的配置来指定使用的 Executor 类型。例如,可以在 mybatis-config.xml 文件中配置 defaultExecutorType 属性:


  
    
  

Executor 的生命周期与作用域

Executor 的生命周期与 SqlSession 的生命周期相同。这意味着每个 SqlSession 都会创建一个 Executor 实例,并且该 Executor 实例只在该 SqlSession 的生命周期内有效。

Executor 的作用域是线程级别的。每个线程都有自己的 SqlSession 和 Executor 实例,因此可以避免线程安全问题。

Executor 的扩展与自定义

MyBatis 允许开发者自定义 Executor。通过实现 org.apache.ibatis.executor.Executor 接口,可以创建自己的 Executor 类型,并将其配置到 M

yBatis 中。这为开发者提供了更大的灵活性,可以根据自己的需求来定制 SQL 执行过程。

例如,可以创建一个 Executor,用于记录 SQL 执行日志,或者用于实现读写分离。

Executor 源码分析(简要)

Executor 接口定义了 SQL 执行的核心方法,例如 update(), query(), flushStatements(), commit(), rollback() 等。不同的 Executor 实现类会根据自己的策略来实现这些方法。

以 SimpleExecutor 为例,其 doUpdate() 方法的核心逻辑如下:

  1. 创建 Statement 对象。
  2. 设置 Statement 对象的参数。
  3. 执行 SQL 语句。
  4. 关闭 Statement 对象。

ReuseExecutor 的 doUpdate() 方法则会首先尝试从缓存中获取 Statement 对象,如果缓存中不存在,则创建新的 Statement 对象。

BatchExecutor 的 doUpdate() 方法会将 SQL 语句添加到批处理列表中,直到调用 flushStatements() 方法时才会真正执行 SQL 语句。

深入理解 Executor 的源码可以帮助开发者更好地理解 MyBatis 的工作原理,从而更好地使用和优化 MyBatis。