mybatis-plus根据某个指定字段批量更新数据库

Java技术 潘老师 2年前 (2022-03-10) 28085 ℃ (0) 扫码查看

一、前言

用过mybatis-plus的同学应该对它的批量更新并不陌生,但mybatis-plus只提供了根据主键ID进行批量更新的updateBatchById的方法,虽然非常好用,但是往往我们会遇到需要根据某个或者多个非ID字段进行批量更新,那这时候该怎么实现呢?

二、可行的方案

方案一

一种方案是直接拿到SqlSessionTemplate,然后获取批量执行的sqlSession对象,类是如下代码:

@Autowired
private SqlSessionTemplate sqlSessionTemplate;
// 新获取一个模式为BATCH,自动提交为false的session
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
static final BATCH_SIZE = 1000;
XxxMapper xxMapper = session.getMapper(XxxMapper.class);
int size = updateList.size();
try {
    for(int i=0; i < size; i++) {
        xxMapper.updateByXxx(updateList.get(i));
        if(i % BATCH_SIZE == 0 || i == size-1){
            //手动每1000个一提交,提交后无法回滚
            session.commit();
            //清理缓存,防止溢出
            session.clearCache();
        }
    }
}catch (Exception e) {
    session.rollback();
} finally {
    session.close();
}

这其实就是使用了mybatis自身的方法,毕竟mybatis-plus只是对mybatis的补充,mybatis的所有功能还是照常可以使用的。这是一种方案,具体的就不展开了。

方案二

第二种方案就是我们仿照mybatis-plus的updateBatchById的方法仿写一个根据指定字段批量更新的方法,因此我们先看下updateBatchById的源码,具体如下:

public boolean updateBatchById(Collection<T> entityList, int batchSize) {
    String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE_BY_ID);
    return this.executeBatch(entityList, batchSize, (sqlSession, entity) -> {
        ParamMap<T> param = new ParamMap();
        param.put(Constants.ENTITY, entity);
        sqlSession.update(sqlStatement, param);
    });
}
注:Constants.ENTITY的值为“et”,Constants常量类在com.baomidou.mybatisplus.core.toolkit包下

接下来我们模仿实现下mybatis-plus根据某个指定字段批量更新的代码。

1、参考上面的代码,我们仿写一个根据指定的字段来批量更新数据库的代码,比如我这里只针对UserEntity,在UserServiceImpl下(该实现类是继承了mybatis-plus的ServiceImpl的)新增如下代码:

public boolean updateBatchByQueryWrapper(Collection<UserEntity> entityList, Function<UserEntity, QueryWrapper> queryWrapperFunction) {
    String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE);
    return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
        ParamMap param = new ParamMap();
        param.put(Constants.ENTITY, entity);
        param.put(Constants.WRAPPER, queryWrapperFunction.apply(entity));
        sqlSession.update(sqlStatement, param);
    });
}
注意:

1)这里使用了Function函数式接口,如果不知道请查看Java函数式编程入门学习举例与优点详解
2)batchSize这里默认使用DEFAULT_BATCH_SIZE,也是mybatis-plus中的默认值1000,当然你也可以保留该入参
3)主要核心的修改地方是以下两部分:

// SqlMethod.UPDATE_BY_ID改为SqlMethod.UPDATE
String sqlStatement = this.getSqlStatement(SqlMethod.UPDATE);
//和新增如下的wapper,即更新条件
param.put(Constants.WRAPPER, queryWrapperFunction.apply(entity));

2、实现了根据指定字段批量更新代码应该如何去使用?
我们只需调用类似如下如下代码,比如我们这里根据username更新:

userService.updateBatchByQueryWrapper(userList, user->new QueryWrapper<>().eq("username",user.getUsername()));

如果你有多个更新条件,就构建对应的QueryWrapper就可以了,到此该问题就解决了。

总结

好了,以上就是mybatis-plus根据某个指定字段实现批量更新数据库的全部内容。如果你有更好的方案,请留言。


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/java/4641.html
喜欢 (29)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】