一個mybatis處理batch的插件,相似於pageHelper插件

編寫mybatis批量處理插件

編寫該插件的目的是項目中常常會有一些須要批處理的狀況,固然Mysql支持insert() values(),()....,()語法,能夠間接達到批量提交的目的。可是在update的時候就不行了。
本插件基於mybatis-3.4.4。實現原理:若是上下文中須要開啓批處理,那麼我就用BatchExecutor代替原先的SimpleExecutor執行器。 插件實現類:java

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "commit", args = {boolean.class}),
        @Signature(type = Executor.class, method = "close", args = {boolean.class})
    }
)
public class BatchHelperIntercept implements Interceptor {

    private int batchCommit = 0;

    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        Executor target = (Executor)invocation.getTarget();
        Method method = invocation.getMethod();
        if(StringUtils.equals(method.getName(),"update") && MybatisBatchHelper.needBatch()) {
            MappedStatement ms = (MappedStatement)invocation.getArgs()[0];
            //須要批量提交
            BatchExecutor batchExecutor = MybatisBatchHelper.getBatchExecutor();
            if (batchExecutor == null) {
                batchExecutor = new BatchExecutor(ms.getConfiguration(), target.getTransaction());
                MybatisBatchHelper.setBatchExecutor(batchExecutor);
            }
            Object resObject = method.invoke(batchExecutor, invocation.getArgs());
            MybatisBatchHelper.increment();
            if(this.batchCommit > 0 && MybatisBatchHelper.getBatchCommit() == this.batchCommit){
                //執行executeBatch
                batchExecutor.flushStatements();
            }
            return resObject;
        }
        BatchExecutor batchExecutor = MybatisBatchHelper.getBatchExecutor();
        boolean hasBatchExecutor = batchExecutor != null;
        if(StringUtils.equals(method.getName(),"commit") && hasBatchExecutor){
            return method.invoke(batchExecutor, invocation.getArgs());
        }
        if(StringUtils.equals(method.getName(),"close") && hasBatchExecutor){
            MybatisBatchHelper.clear();
            return method.invoke(batchExecutor, invocation.getArgs());
        }
        return method.invoke(target,invocation.getArgs());
    }

    @Override
    public Object plugin(Object target) {
        //包裝插件
        return Plugin.wrap(target,this);
    }

    @Override
    public void setProperties(Properties properties) {
        this.batchCommit = Integer.parseInt(properties.getProperty("batchCommit","0"));
    }
}

spring-boot2 自動配置類git

@Configuration
@ConditionalOnBean({SqlSessionFactory.class})
@EnableConfigurationProperties({MybatisBatchProperties.class})
@AutoConfigureAfter({MybatisAutoConfiguration.class})
public class MybatisBatchAutoConfiguration {

    @Autowired
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @Autowired
    private MybatisBatchProperties mybatisBatchProperties;

    @PostConstruct
    public void addPageInterceptor() {
        BatchHelperIntercept interceptor = new BatchHelperIntercept();
        Properties properties = mybatisBatchProperties.getProperties();
        interceptor.setProperties(properties);
        Iterator<SqlSessionFactory> it = this.sqlSessionFactoryList.iterator();

        while(it.hasNext()) {
            SqlSessionFactory sqlSessionFactory = it.next();
            sqlSessionFactory.getConfiguration().addInterceptor(interceptor);
        }
    }
}

用法

在spring-boot2項目中引用JAR包github

<dependency>
   <groupId>com.github.liuax</groupId>
   <artifactId>mybatis-batch-starter</artifactId>
   <version>1.0.0</version>
</dependency>

在須要批量提交的代碼開啓批處理:spring

MybatisBatchHelper.startBatch();

測試狀況

插入

代碼sql

@Override
    public void test1(){
        //MybatisBatchHelper.startBatch();
        for(int i = 0;i<5000;i++){
            OssParseLog log = new OssParseLog();
            log.setBatchId(i+"");
            log.setCrtTime(new Date());
            log.setName("aaaa");
            log.setHhmmss("112233");
            log.setType("test1");
            log.setApp("0001");
            baseManagr.insertSelective(log);
        }
    }

未開啓批處理的狀況:mybatis

2019-05-03 08:27:09.429 DEBUG 11236 --- [           main] c.v.f.b.b.s.m.O.insertSelective          : <==    Updates: 1
84524:ms
ok

開啓批處理的狀況:app

2019-05-03 09:17:40.355 DEBUG 13036 --- [           main] c.v.f.b.b.s.m.O.insertSelective          : ==> Parameters: 4999(String), 112233(String), test1(String), 0001(String), aaaa(String), 2019-05-03 09:17:40.355(Timestamp)
1834:ms
ok

更新

代碼ide

@Override
    public void test2() {
        MybatisBatchHelper.startBatch();
        for(int i = 0;i<5000;i++){
            OssParseLog log = new OssParseLog();
            log.setBatchId(i+"");
            log.setCrtTime(new Date());
            log.setName("bbbbb");
            log.setHhmmss("112233");
            log.setType("test2");
            log.setApp("0001");
            Example example = Example.builder(OssParseLog.class).andWhere(Sqls.custom()
            .andEqualTo("batchId",i+"")).build();
            baseManagr.updateSelectiveByExample(log,example);
        }
    }

未開啓批處理的狀況:spring-boot

2019-05-03 09:25:04.431 DEBUG 9224 --- [           main] c.v.f.b.b.s.m.O.updateByExampleSelective : <==    Updates: 1
87424:ms
ok

開啓批處理的狀況:測試

2019-05-03 09:27:40.063 DEBUG 10984 --- [           main] c.v.f.b.b.s.m.O.updateByExampleSelective : ==> Parameters: 4999(String), 112233(String), test2(String), 0001(String), ccccc(String), 2019-05-03 09:27:40.063(Timestamp), 4999(String)
3744:ms
ok
相關文章
相關標籤/搜索