mybatis-plus根据任意字段saveOrUpdateBatch更新插入的方法实现
mybatisplus Iservice接口下的saveOrUpdateBatch方法默认是根据主键来决定是要更新还是插入的,如果要根据其他字段(必须是唯一约束,唯一约束字段可以是多个)更新的话,则需要在项目的service层重写该方法。
方法源码
@Transactional(
rollbackFor = {Exception.class}
)
public boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize) {
TableInfo tableInfo = TableInfoHelper.getTableInfo(this.entityClass);
Assert.notNull(tableInfo, "error: can not execute. because can not find cache of TableInfo for entity!", new Object[0]);
String keyProperty = tableInfo.getKeyProperty();
Assert.notEmpty(keyProperty, "error: can not execute. because can not find column for id from entity!", new Object[0]);
return SqlHelper.saveOrUpdateBatch(this.entityClass, this.mapperClass, this.log, entityList, batchSize, (sqlSession, entity) -> {
Object idVal = ReflectionKit.getFieldValue(entity, keyProperty);
return StringUtils.checkValNull(idVal) || CollectionUtils.isEmpty(sqlSession.selectList(this.getSqlStatement(SqlMethod.SELECT_BY_ID), entity));
}, (sqlSession, entity) -> {
MapperMethod.ParamMap<T> param = new MapperMethod.ParamMap();
param.put("et", entity);
sqlSession.update(this.getSqlStatement(SqlMethod.UPDATE_BY_ID), param);
});
}从源码中可以看出实现saveOrUpdateBatch的主要方法就是SqlHelper.saveOrUpdateBatch
public static <E> boolean saveOrUpdateBatch(Class<?> entityClass, Class<?> mapper, Log log, Collection<E> list, int batchSize, BiPredicate<SqlSession, E> predicate, BiConsumer<SqlSession, E> consumer) {
String sqlStatement = getSqlStatement(mapper, SqlMethod.INSERT_ONE);
return executeBatch(entityClass, log, list, batchSize, (sqlSession, entity) -> {
if (predicate.test(sqlSession, entity)) {
sqlSession.insert(sqlStatement, entity);
} else {
consumer.accept(sqlSession, entity);
}
});
}该方法的最后两个参数predicate,consumer
predicate 这个函数是用于判断是否要进行插入操作 true插入,false:则通过consumer 函数执行更新
方法改造
注意:写在项目操作对应表的service层
首先在service层定义接口
boolean saveOrUpdateBatchByAgentIdAndPeriodAndType(List<Entity> list);
类为数据库表对应的实体类 ,agentId,period,type,这个三个字段为表的唯一约束,即当表中存在这三个字段组合对应的记录时则进行更新操作,不存在则进行插入操作
service层接口实现
@Transactional(rollbackFor = Exception.class)
@DS("XXXX")//如果为多数据源,这里要指明具体操作的数据源名称
public boolean saveOrUpdateBatchByAgentIdAndPeriodAndType(List<Entity> list) {
return SqlHelper.saveOrUpdateBatch(entityClass, this.mapperClass, super.log, list, DEFAULT_BATCH_SIZE, (sqlSession, entity) -> {//这里主要是查询唯一约束对应的记录是否存在
LambdaQueryWrapper<Entity> queryWrapper = Wrappers.<Entity>lambdaQuery()
.eq(Entity::getAgentId, entity.getAgentId()).eq(Entity::getPeriod,entity.getPeriod())
.eq(Entity::getType,entity.getType());
Map<String, Object> map = CollectionUtils.newHashMapWithExpectedSize(1);
map.put(Constants.WRAPPER, queryWrapper);
return CollectionUtils.isEmpty(sqlSession.selectList(getSqlStatement(SqlMethod.SELECT_LIST), map));
}, (sqlSession, entity) -> {
LambdaUpdateWrapper<Entity> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();
lambdaUpdateWrapper.eq(Entity::getAgentId, entity.getAgentId()).eq(Entity::getPeriod,entity.getPeriod())
.eq(Entity::getType,entity.getType());
Map<String, Object> param = CollectionUtils.newHashMapWithExpectedSize(2);
param.put(Constants.ENTITY, entity);
param.put(Constants.WRAPPER, lambdaUpdateWrapper);
sqlSession.update(getSqlStatement(SqlMethod.UPDATE), param);
});
}非批量的saveOrUpdate也可以按照这种方式进行改造
到此这篇关于mybatis-plus根据任意字段saveOrUpdateBatch更新插入的方法实现的文章就介绍到这了,更多相关mybatis-plus saveOrUpdateBatch内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringBoot项目中Maven剔除无用Jar引用的最佳实践
在 Spring Boot 项目开发中,Maven 是最常用的构建工具之一,通过 Maven,我们可以轻松地管理项目所需的依赖,而,随着项目的复杂化,无用的 Jar 包引用可能会逐渐增多,本文旨在详细解析如何在 Spring Boot 项目中剔除无用的 Jar 引用,需要的朋友可以参考下2025-01-01
SpringMVC中事务是否可以加在Controller层的问题
这篇文章主要介绍了SpringMVC中事务是否可以加在Controller层的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-02-02
详解Java并发包中线程池ThreadPoolExecutor
ThreadPoolExecutor是Java语言对于线程池的实现。线程池技术使线程在使用完毕后不回收而是重复利用。如果线程能够复用,那么我们就可以使用固定数量的线程来解决并发问题,这样一来不仅节约了系统资源,而且也会减少线程上下文切换的开销2021-06-06


最新评论