本文主要是介绍mybatis-plus如何根据任意字段saveOrUpdateBatch,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《mybatis-plus如何根据任意字段saveOrUpdateBatch》MyBatisPlussaveOrUpdateBatch默认按主键判断操作类型,若需按其他唯一字段(如agentId、pe...
使用场景
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, androidBiConsumer<SqlSession, E>php; 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<http://www.chinasem.cnString, 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(Constantswww.chinasem.cn.ENTITY, entity); param.put(Constants.WRAPPER, lambdaUpdateWrapper); sqlSession.update(getSqlStatement(SqlMethod.UPDATE), param); }); }
非批量的saveOrUpdate也可以按照这种方式进行改造
总结
这篇关于mybatis-plus如何根据任意字段saveOrUpdateBatch的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!