mybatis-plus根据指定字段批量,删除、修改实现过程
作者:单人影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的,可以试一试。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
