Executor
Mybatis中所有的Mapper语句的执行都是通过Executor进行的,Executor是Mybatis的一个核心接口。
Executor接口的实现类有BaseExecutor和CachingExecutor,而BaseExecutor的子类又有SimpleExecutor、ReuseExecutor和BatchExecutor,但BaseExecutor是一个抽象类,只实现一些公共的封装,而把真正的核心实现通过方法抽象出来给子类实现,如doUpdate()、doQuery();CachingExecutor只是在Executor的基础上加入缓存的功能,底层还是通过Executor调用的,真正有作用的Executor只有SimpleExecutor、ReuseExecutor和BatchExecutor。Executor是跟SqlSession绑定在一起的,每一个SqlSession拥有一个新的Executor对象,由Configuration创建。
SimpleExecutor是Mybatis执行Mapper语句时,默认使用的Executor,提供最基本的Mapper语句执行功能,没有过多的封装的
ReuseExecutor,是可以重用的Executor。重用的是Statement对象,会在内部利用一个Map把创建的Statement都缓存起来,每次在执行一条SQL语句时,都会去判断之前是否存在基于该SQL缓存的Statement对象,存在之前缓存的Statement对象对应的Connection还没有关闭的时候,就继续用之前的Statement对象,否则将创建一个新的Statement对象,并将其缓存起来。因为每一个新的SqlSession都有一个新的Executor对象,所以缓存在ReuseExecutor上的Statement的作用域是同一个SqlSession。
BatchExecutor的设计主要是用于做批量更新操作的。其底层会调用Statement的executeBatch()方法实现批量操作。
使用BaseExecutor是怎么确定的呢?是通过在创建SqlSession的时候确定的。SqlSession都是通过SqlSessionFactory的openSession()创建的,SqlSessionFactory提供了一系列的openSession()方法。
public interface SqlSessionFactory { SqlSession openSession(); SqlSession openSession(boolean autoCommit); SqlSession openSession(Connection connection); SqlSession openSession(TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType); SqlSession openSession(ExecutorType execType, boolean autoCommit); SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level); SqlSession openSession(ExecutorType execType, Connection connection); Configuration getConfiguration(); }
SqlSessionFactory提供的方法来看,一共提供了两类创建SqlSession的方法,一类是没有指定ExecutorType的,一类是指定了ExecutorType的。很显然,指定了ExecutorType时将使用ExecutorType对应类型的Executor。ExecutorType是一个枚举类型,有SIMPLE、REUSE和BATCH三个对象。
没有指定ExecutorType时,将使用默认的Executor。Mybatis默认的Executor是SimpleExecutor,可以通过Mybatis的全局配置defaultExecutorType来进行配置,其可选值也是SIMPLE、REUSE和BATCH。
<setting name="defaultExecutorType" value="SIMPLE"/>
当Mybatis整合Spring后,Spring扫描后生成的Mapper对象,底层使用的SqlSession是用的默认的Executor。如果需要在程序中使用非默认的Executor时,可以在Spring的bean容器中声明SqlSessionFactoryBean,然后在需要指定Executor的类中注入SqlSessionFactory,通过SqlSessionFactory来创建指定ExecutorType的SqlSession。
使用Mybatis的BatchExecutor进行批量操作的示例。在示例中创建一个使用BatchExecutor的SqlSession,也可以是SqlSessionTemplate,其实现SqlSession接口,底层通过一个SqlSession代理进行相应的操作。然后在循环中一次调用对应Mapper的新增操作,相当于调用BatchExecutor的doUpdate(),最后调用SqlSession的commit()方法提交事务,在SqlSession的commit()中会调用Executor的commit(),从而导致了executeBatch()的发生。
@Test public void testExecutor() { SqlSession session = this.sessionFactory.openSession(ExecutorType.BATCH); UserMapper mapper = session.getMapper(UserMapper.class); User user = null; for (inti = 0; i < 10; i++) { user = new User(); user.setName("Name_" + i); user.setEmail("email"); mapper.insert(user); } // 批量插入User session.commit();// 提交事务时批量操作才会写入数据库 session.close(); }
参考:
http://elim.iteye.com/blog/2350749
浙公网安备 33010602011771号