Mybatis批量插入或更新(根据指定字段更新)

本文详细解析了MyBatis如何利用ON DUPLICATE KEY UPDATE特性实现批量更新,当记录存在时更新,不存在时插入。通过具体实例说明了唯一索引在这一过程中的作用,并介绍了DAO层XML配置中foreach元素的使用方法。

        Mybatis批量更新运用ON DUPLICATE KEY UPDATE ,如果记录不存在则插入,存在则更新。那么这个记录是否存在根据什么判断?规则如下:

      如果你插入的记录导致UNIQUE索引重复,则认为这条记录存在。比如我创建表的时候设置的唯一索引为字段email,那么如果email重复时则执行更新,否则插入。当如果唯一索引为多个字段时如name,tchCode,那么当name,tchCode两个字段完全重复时候,此时就要执行更新语句。当然满足一部分唯一索引是不会触发更新操作的,此时会执行插入操作。

        接下来dao层:

        xml中的代码为:

update的字段名都是表中的字段名,包括values()中的

foreach元素的属性主要有 item,index,open,close ,separator,collection。

  1. item表示集合中每一个元素进行迭代时的别名
  2. index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置
  3. open表示该语句以什么开始
  4. close表示以什么结束
  5. separator表示在每次进行迭代之间以什么符号作为分隔符
  6. collection传入的是参数,可以是list,array.传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array

 

 

<think>好的,我需要帮助用户找到使用MyBatis-Plus根据指定字段批量更新数据的Java示例。首先,我应该回顾用户提供的引用内容,看看是否有相关的信息。用户引用的内容提到了MyBatis-Plus的批量操作优化、参数映射、动态XML拼接以及自定义批量插入。特别是引用[1]中的动态XML示例,展示了批量更新状态的方法,这可能与用户的需求相关。 接下来,用户需要的是批量更新指定字段的示例。MyBatis-Plus默认的saveBatch方法可能无法满足指定字段的需求,因此需要自定义SQL。根据引用[1]中的例子,使用<update>标签和<foreach>循环来构建IN条件,这可以用来批量更新。但用户可能需要根据不同的字段进行更新,而不仅仅是状态。 我应该考虑如何构造一个动态的UPDATE语句,允许根据条件更新多个字段。例如,如果用户需要根据id更新多个记录的name和email字段,可能需要传递一个包含实体对象的列表,并在XML中遍历这个列表,为每个对象生成相应的更新语句。不过,批量更新通常有两种方式:一种是使用Case When的方式在一条SQL中更新多条记录,另一种是分批次执行多个更新语句。 引用[1]中提到分批次提交以避免SQL过长,这可能意味着在XML中使用<foreach>生成多个UPDATE语句,然后通过MyBatis的ExecutorType.BATCH来执行。此外,用户需要指定更新字段,可能需要使用<set>标签和条件判断,如<if test="field != null">,来动态设置字段。 另外,引用[2]中提到的@TableField注解和类型处理器可能不直接相关,但需要注意实体类字段的映射是否正确,特别是在批量操作时确保字段正确填充。 综合这些信息,我应该提供一个Java示例,结合MyBatis-Plus的Mapper接口、自定义的XML映射文件,使用动态SQL实现批量更新指定字段。同时需要提醒用户关于性能优化的点,比如分批次处理、参数配置如rewriteBatchedStatements等。 最后,用户可能需要了解如何避免常见问题,比如SQL注入、字段覆盖错误,以及如何确保事务管理。因此,在回答中应该包含这些注意事项,并引用提供的参考资料来支持建议。</think>以下是使用MyBatis-Plus实现指定字段批量更新的完整Java示例,包含三种常见实现方式: ### 方式一:动态SQL批量更新(单条SQL) ```xml <!-- XML映射文件 --> <update id="updateBatchByCustom"> UPDATE user SET name = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.name} </foreach> END, age = CASE id <foreach collection="list" item="item"> WHEN #{item.id} THEN #{item.age} </foreach> END WHERE id IN ( <foreach collection="list" item="item" separator=","> #{item.id} </foreach> ) </update> ``` ```java // Mapper接口 public interface UserMapper extends BaseMapper<User> { int updateBatchByCustom(@Param("list") List<User> users); } // 使用示例 List<User> updateList = Arrays.asList( new User(1L, "Alice", 25), new User(2L, "Bob", 30) ); userMapper.updateBatchByCustom(updateList); ``` ### 方式二:批量执行模式(多条SQL) ```java // 开启批量模式 SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory() .openSession(ExecutorType.BATCH); UserMapper batchMapper = sqlSession.getMapper(UserMapper.class); for (User user : updateList) { LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper .set(User::getName, user.getName()) .set(User::getAge, user.getAge()) .eq(User::getId, user.getId()); batchMapper.update(null, wrapper); } sqlSession.commit(); sqlSession.close(); ``` ### 方式三:条件构造器批量更新 ```java // 单字段批量更新示例 LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper.in(User::getId, Arrays.asList(1L, 2L)) .set(User::getStatus, 1); userMapper.update(null, wrapper); // 多字段动态更新(需循环处理) updateList.forEach(user -> { userMapper.updateById(user); // 根据@Version注解自动乐观锁控制 }); ``` ### 关键优化建议: 1. **分批次处理**:当数据量超过1000条时,建议分批次处理(每批500条)[^1] 2. **MySQL参数配置**:添加`rewriteBatchedStatements=true`到连接参数,提升批量操作性能[^1] 3. **空值过滤**:使用`<if>`标签过滤空值字段,避免误覆盖数据[^1] ```xml <set> <if test="name != null">name=#{name},</if> <if test="age != null">age=#{age}</if> </set> ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值