编写该插件的目的是项目中常常会有一些须要批处理的状况,固然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