mybatis-plus根据指定字段批量,删除、修改实现过程

 更新时间:2026年04月23日 10:01:30   作者:单人影i  
本文介绍了三种MyBatis-Plus进行批量删除和修改的方法,第一种是避免手写SQL,第二种是手动获取SqlSessionTemplate,第三种是重写executeBatch方法,虽然批量处理效率较低,但对于不追求性能且不想手写SQL的场景,可以尝试这种方法

mybatis-plus根据指定字段批量删除修改

方案一

手写SQL

  • 这个就不说了,就是因为不想手写SQL 所以才有这篇博客

方案二

手动获取SqlSessionTemplate 就是把mybatis plus 干的事自己干了

// 这种方法就是把mybatis的活在干一遍,还是一条一条处理的.只是共用一个session连接
@Autowired
private SqlSessionTemplate sqlSessionTemplate;

// 新获取一个模式为BATCH,自动提交为false的session
SqlSession session = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH,false);
static final BATCH_SIZE = 1000;
// XxxMapper 为 对应的mapper文件
XxxMapper xxMapper = session.getMapper(XxxMapper.class);
int size = updateList.size();
try {
    for(int i=0; i < size; i++) {
    	// updateByXxx 写好的单条数据的方法
        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();
}

方案三 

重写 executeBatch 方法

	// mybatis plus 源码
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean updateBatchById(Collection<T> entityList, int batchSize) {
        String sqlStatement = getSqlStatement(SqlMethod.UPDATE_BY_ID);
        return executeBatch(entityList, batchSize, (sqlSession, entity) -> {
            MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap<>();
            param.put(Constants.ENTITY, entity);
            sqlSession.update(sqlStatement, param);
        });
    }

mybatis plus 的 executeBatch

参考 mybatis plus 的updateBatchById 方法.

  • 调用处:
//删除方法 deleteList  是要删除的主键list
List<String> deleteList = new ArrayList<>();
dao.batchDelete(deleteList, delete -> new QueryWrapper<String>().eq("xx", delete));

// 修改方法 OBJ 代码表对象
List<OBJ> updateList = new ArrayList<>();
dao.batchUpdate(updateList, update -> new LambdaQueryWrapper<OBJ>()
                        .eq(OBJ::getProductId, update.getProductId()));


  • 接口:
    boolean batchUpdate(List<OBJ> updateList, Function<OBJ, LambdaQueryWrapper> queryWrapperFunction);

    boolean batchDelete(List<String> deleteList, Function<String, QueryWrapper> queryWrapperFunction);
  • 重写方法 实现:
	@Override
    public boolean batchUpdate(List<OBJ> entityList, Function<OBJ, LambdaQueryWrapper> function) {
        return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
            ParamMap param = new ParamMap();
            param.put(Constants.ENTITY, entity);
            param.put(Constants.WRAPPER, function.apply(entity));
            sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE), param);
        });
    }

    @Override
    public boolean batchDelete(List<String> deleteList, Function<String, QueryWrapper> function) {
        return this.executeBatch(deleteList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
            ParamMap param = new ParamMap();
            param.put(Constants.ENTITY, entity);
            param.put(Constants.WRAPPER, function.apply(entity));
            sqlSession.delete(this.getSqlStatement(SqlMethod.DELETE), param);
        });
    }
	// 也可以传入一个LambdaUpdateWrapper 来制定更新
    @Override
    public boolean batchUpdate2(List<ContProductAbstractLocalDO> entityList, Function<ContProductAbstractLocalDO, LambdaUpdateWrapper> function) {
        return this.executeBatch(entityList, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {
            ParamMap param = new ParamMap();
            param.put(Constants.ENTITY, null);
            param.put(Constants.WRAPPER, function.apply(entity));
            sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE), param);
        });
    }
示例 : 指定执行的SQL 和字段
   private LambdaUpdateWrapper<OBJ> getUpdateWrapper(OBJupdate) {
        retur new LambdaUpdateWrapper<OBJ>()
                .eq(OBJ::getxx, update.xx())
                .set(OBJ::getxxx, update.xxxx());

总结

这种写法其实批量的效率还是比较慢的,如果对性能没有要求,并且还不想手写SQL的,可以试一试。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java中的interrupted()和isInterrupted()

    Java中的interrupted()和isInterrupted()

    这篇文章主要介绍了Java中的interrupted()和isInterrupted()摸下面文章围绕interrupted()和isInterrupted()的相关资料展开详细内容,需要的小伙伴乐意参考下面下面文章具体价绍,希望对大家有所帮助
    2021-11-11
  • springboot中动态权限实时管理的实现详解

    springboot中动态权限实时管理的实现详解

    这篇文章主要为大家详细介绍了如何简单实现一个在springboot中动态权限的实时管理,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2024-10-10
  • SpringBoot配置与使用maven的方法

    SpringBoot配置与使用maven的方法

    本文介绍了如何在IntelliJ IDEA中创建和配置Maven项目,包括创建过程、目录结构、pom.xml文件的用途、依赖管理、生命周期、配置选项以及如何下载依赖和配置本地仓库,感兴趣的朋友跟随小编一起看看吧
    2026-01-01
  • Springboot使用Redis实现定时任务的三种方式

    Springboot使用Redis实现定时任务的三种方式

    本文介绍了三种Redis定时任务实现方式,键空间通知,有序集合轮询,分布式锁,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-06-06
  • 详解java中spring里的三大拦截器

    详解java中spring里的三大拦截器

    在本篇文章里我们给大家详细讲述了java中spring里的三大拦截器相关知识点以及用法代码,需要的朋友们学习下。
    2018-10-10
  • MyBatis中$与#的区别解析

    MyBatis中$与#的区别解析

    文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(Prepared Statement),并将参数值作为预处理语句的参数绑定到SQL语句中。使用。
    2025-07-07
  • Spring Boot中的WebSocketMessageBrokerConfigurer接口使用

    Spring Boot中的WebSocketMessageBrokerConfigurer接口使用

    在SpringBoot中,我们可以使用 WebSocketMessageBrokerConfigurer接口来配置WebSocket消息代理,以实现实时通信,具有一定的参考价值,感兴趣的可以了解一下
    2023-11-11
  • java局域网聊天小程序

    java局域网聊天小程序

    这篇文章主要为大家详细介绍了java局域网聊天小程序,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • 解决Java API不能远程访问HBase的问题

    解决Java API不能远程访问HBase的问题

    这篇文章主要介绍了解决Java API不能远程访问HBase的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • java多线程处理执行solr创建索引示例

    java多线程处理执行solr创建索引示例

    这篇文章主要介绍了java多线程处理执行solr创建索引示例,需要的朋友可以参考下
    2014-02-02

最新评论