文档章节

一个mybatis处理batch的插件,类似于pageHelper插件

my_juke
 my_juke
发布于 05/03 09:39
字数 650
阅读 4
收藏 0

编写mybatis批量处理插件

编写该插件的目的是项目中经常会有一些需要批处理的情况,当然Mysql支持insert() values(),()....,()语法,可以间接达到批量提交的目的。但是在update的时候就不行了。
本插件基于mybatis-3.4.4。实现原理:如果上下文中需要开启批处理,那么我就用BatchExecutor代替原先的SimpleExecutor执行器。 插件实现类:

@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 自动配置类

@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包

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

在需要批量提交的代码开启批处理:

MybatisBatchHelper.startBatch();

测试情况

插入

代码

@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);
        }
    }

未开启批处理的情况:

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

开启批处理的情况:

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

更新

代码

@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);
        }
    }

未开启批处理的情况:

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

© 著作权归作者所有

my_juke
粉丝 4
博文 34
码字总数 22261
作品 0
深圳
私信 提问
Mybatis 分页插件 PageHelper 5.0.0 发布

Mybatis分页插件 - PageHelper PageHelper 5.0.0 发布了。如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件。分页插件支持任何复杂的单表、多表分页,部分特殊情况请...

Liuzh_533
2017/01/03
22.3K
39
pagehelper/Mybatis-PageHelper

Mybatis分页插件 - PageHelper 如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件。 分页插件支持任何复杂的单表、多表分页,部分特殊情况请看重要提示。 想要使用分页...

java梦想家01
2015/08/03
679
0
MyBaties分页插件PageHelper的简单使用

抛出问题: 如果想要将现有的select语句改为支持分页功能的查询语句该怎么做呢? 最简单的一种做法就是将所有的select语句都加上limit来实现分页,这种做法有什么问题呢? 有没有一种简便方法...

嘴角轻扬30
2018/12/10
89
0
SpringCloud集成 Mybatis分表插件shardbatis 踩坑日志及其原理分析

公司新开发的系统数据量过大,需要进行分表处理,我在网上浏览一圈,选中了Shardbatis,原因有二: 1.公司项目本身集成了Mybatis,而Shardbatis是其插件,引入方便; 2.Sharbatis十分轻便,只...

L墨龙
01/22
195
0
Mybatis 分页插件 3.7.2 发布

Mybatis分页插件 - PageHelper 如果你也在用Mybatis,建议尝试该分页插件,这一定是最方便使用的分页插件。 该插件目前支持以下数据库的物理分页: Oracle Mysql MariaDB SQLite Hsqldb Post...

Liuzh_533
2015/05/15
2.4K
9

没有更多内容

加载失败,请刷新页面

加载更多

精华帖

第一章 jQuery简介 jQuery是一个JavaScript库 jQuery具备简洁的语法和跨平台的兼容性 简化了JavaScript的操作。 在页面中引入jQuery jQuery是一个JavaScript脚本库,不需要特别的安装,只需要...

流川偑
22分钟前
6
0
语音对话英语翻译在线翻译成中文哪个方法好用

想要进行将中文翻译成英文,或者将英文翻译成中文的操作,其实有一个非常简单的工具就能够帮助完成将语音进行翻译转换的软件。 在应用市场或者百度手机助手等各大应用渠道里面就能够找到一款...

401恶户
34分钟前
3
0
jenkins 插件下载加速最终方案

推荐做法 1、告诉jenkins 我哪些插件需要更新 jenkins插件清华大学镜像地址 https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json 1.进入jenkins系统管理 2.进入插件管...

vasks
40分钟前
4
0
composer爆错:zlib_decode():data error

解决办法:先用 composer diagnose 命令检测 然后 composer self-update 更新composer版本 最后执行 composer update 或者 composer install composer 切换阿里云镜像 用起来还快 composer c...

koothon
46分钟前
4
0
shangcheng-my

1.数据库主键、外键类型为bigint,那么在后台应该用什么类型的变量定义? 后台用string接收,因为前段传过来的一般都是json字符串,后台直接接收,mysql是可以吧数字类型的字符串转换为对应的...

榴莲黑芝麻糊
昨天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部