編寫該插件的目的是項目中常常會有一些須要批處理的狀況,固然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