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也可以按照这种方式进行改造

  • 8
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: 可以使用Mybatis-plus提供的update方法来修改本身字段。例如: ```java User user = new User(); user.setId(1L); user.setName("new name"); user.setAge(20); userMapper.updateById(user); ``` 这样就可以将id为1的用户的name和age字段更新为"new name"和20。 ### 回答2: 在使用MyBatis-Plus修改本身字段时,可以通过以下步骤进行操作: 首先,在数据库表中定义需要修改的字段。假设我们有一个名为user的表,其中有一个字段为name。 其次,通过MyBatis-Plus的实体类,例如User实体类,在对应的字段上添加@TableField注解。这样可以告诉MyBatis-Plus字段需要被修改。 然后,在进行数据修改时,通过MyBatis-Plusupdate方法来更新表中的数据。可以使用Wrapper类来构建修改条件,然后使用set方法来设置修改的字段值。 最后,调用update方法执行修改操作。 下面是一个示例代码: ```java // 导入需要的类 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.service.additional.update.impl.UpdateChainWrapper; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService { @Autowired private UserMapper userMapper; public void updateUser(String id, String name) { // 创建修改条件 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", id); // 设置修改字段值 User user = new User(); user.setName(name); // 执行更新操作 userMapper.update(user, wrapper); } } ``` 在上述代码中,首先创建了一个UpdateWrapper对象,并指定修改条件为id等于指定的id。然后创建一个User对象,并设置需要修改的字段值。最后调用update方法执行更新操作。 通过以上步骤,就可以实现使用MyBatis-Plus修改本身字段的功能。 ### 回答3: Mybatis-plus是一款基于Mybatis的增强工具,在实现数据库操作时提供了很多便捷的功能。要修改本身字段,可以通过以下步骤实现: 1. 创建一个实体类,映射到数据库的表中。实体类的属性要与表的字段一一对应,并提供对应的getter和setter方法。 2. 在配置文件中配置数据源和Mybatis-plus的相关配置。 3. 编写对应的Mapper接口,通过继承Mybatis-plus中的BaseMapper接口或者自定义接口,定义需要执行的数据库操作方法。 4. 在Mapper接口中定义一个修改数据的方法,并使用Mybatis-plus提供的注解@Update来完成字段的修改。该注解中的value属性可以编写更新语句,使用#{属性名}来引用实体类中的属性。 5. 在Service层中调用Mapper接口中定义的修改方法,将需要修改的数据作为参数传入。 6. 在控制层中调用Service层中的方法,完成数据修改操作。 通过以上步骤,可以使用Mybatis-plus修改本身字段。在修改时需要注意保证实体类中的属性与数据库表的字段一一对应,以及正确配置相关的Mapper接口和注解。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值