deepseek回答MyBatis-Plus UpdateWrapper setEntity() 示例代码

以下是 MyBatis-Plus 中 UpdateWrapper 结合 setEntity() 的示例代码及详细说明,适用于不同场景的更新操作:


‌1. 基础用法:更新实体中的非空字段‌

将实体对象中的非空字段作为更新内容,结合条件更新指定记录。

javaCopy Code
 
User user = new User(); user.setName("John"); // 设置要更新的字段 user.setAge(25); // 设置要更新的字段 user.setEmail(null); // 不更新 email(值为 null) UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 1) // WHERE id = 1 .setEntity(user); // 绑定实体对象 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name='John', age=25 WHERE id=1;

‌说明‌:

  • setEntity() 会自动提取实体对象中 ‌非空字段‌ 作为更新内容。
  • email 字段因值为 null 被忽略。

‌2. 动态更新:仅更新提交的非空字段‌

结合业务逻辑动态更新部分字段(如用户修改个人信息)。

javaCopy Code
 
// 假设前端提交的修改数据(部分字段可能为空) User userParam = new User(); userParam.setName("Alice"); userParam.setEmail(""); // 空字符串(可能表示清空邮箱) UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 1001) .setEntity(userParam); userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name='Alice', email='' WHERE id=1001;

‌说明‌:

  • email 字段被更新为空字符串(非 null 值)。
  • 若字段值为 null(如 userParam.setEmail(null)),则不会更新。

‌3. 强制更新 null 字段‌

通过配置全局策略或使用 set() 方法强制更新 null 值。

‌方案1:全局配置(忽略 null 改为更新 null)‌

yamlCopy Code
 
# application.yml mybatis-plus: global-config: db-config: update-strategy: not_empty # 默认忽略 null,此处改为非空更新(根据需求调整)

‌方案2:使用 set() 显式覆盖‌

javaCopy Code
 
User user = new User(); user.setName(null); // 希望将 name 设为 null UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 1) .setEntity(user) .set("name", null); // 显式强制更新为 null userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name=null WHERE id=1;

‌4. 与 set() 方法联用(优先级控制)‌

当同时使用 setEntity() 和 set() 时,set() 优先级更高。

javaCopy Code
 
User user = new User(); user.setName("Bob"); user.setAge(30); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.eq("id", 1) .set("age", 40) // 手动设置字段(优先级高于实体对象) .setEntity(user); // 绑定实体对象 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name='Bob', age=40 WHERE id=1; # age=40 覆盖了实体的 age=30

‌5. 复杂条件组合‌

结合 and()or() 等条件构造复杂更新逻辑。

javaCopy Code
 
User user = new User(); user.setStatus(1); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(user) .eq("role", "admin") // WHERE role = 'admin' .and(wq -> wq.lt("age", 18) // AND (age < 18 .or().gt("score", 90)); // OR score > 90) .set("remark", "特殊用户"); // 额外更新 remark 字段 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET status=1, remark='特殊用户' WHERE role='admin' AND (age < 18 OR score > 90);

‌6. 批量更新‌

结合 in() 条件实现批量更新。

javaCopy Code
 
List<Long> ids = Arrays.asList(1001L, 1002L, 1003L); User user = new User(); user.setIsDeleted(1); // 逻辑删除字段 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(user) .in("id", ids); // WHERE id IN (1001, 1002, 1003) userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET is_deleted=1 WHERE id IN (1001, 1002, 1003);

‌注意事项‌

  1. ‌字段覆盖规则‌:set() 方法优先级高于 setEntity()
  2. ‌空值处理‌:默认忽略 null 字段,需通过全局配置或显式 set() 更新 null
  3. ‌性能优化‌:避免全表更新,始终附加有效条件(如 eq("id", value))。
  4. ‌Lambda 安全‌:推荐使用 LambdaUpdateWrapper 避免字段名硬编码:
    javaCopy Code
     
    LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(); wrapper.eq(User::getId, 1) .set(User::getName, "Tom");

通过 setEntity() 可以简化基于实体对象的动态更新操作,结合条件构造器实现灵活的业务需求。

 

------------------------------------------------------------

以下是结合 MyBatis-Plus setEntity() 方法的复杂场景示例代码,涵盖多种业务场景并综合多个技术实现方案:


‌1. 动态更新部分字段 + 复杂条件组合‌

通过实体对象动态更新非空字段,并结合多重嵌套条件筛选目标数据‌57:

javaCopy Code
 
// 实体对象:仅更新非空字段 User user = new User(); user.setName("UpdatedName"); user.setStatus(1); // 状态字段需要更新 LambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(); wrapper.setEntity(user) .eq(User::getRole, "admin") // 基础条件:角色为管理员 .and(wq -> wq .gt(User::getScore, 90) // 嵌套条件:分数>90 .or() .lt(User::getAge, 18) // 或年龄<18 ) .set(User::getUpdateTime, LocalDateTime.now()); // 强制更新时间字段 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name='UpdatedName', status=1, update_time='2025-03-28 14:30:00' WHERE role='admin' AND (score > 90 OR age < 18);

‌2. 批量更新 + 字段运算‌

批量更新符合条件的数据,并对特定字段进行数值运算‌35:

javaCopy Code
 
// 更新所有部门ID为100的员工 User entity = new User(); entity.setBonus(500); // 基础奖金值 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(entity) .setSql("salary = salary + 1000") // 直接操作SQL表达式 .in("dept_id", Arrays.asList(100, 101, 102)) // 批量部门条件 .le("hire_date", LocalDate.of(2020, 1, 1)); // 入职日期筛选 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET bonus=500, salary = salary + 1000 WHERE dept_id IN (100,101,102) AND hire_date <= '2020-01-01';

‌3. 联表更新模拟‌

通过子查询实现类联表更新效果(需数据库支持)‌58:

javaCopy Code
 
// 根据订单表更新用户等级 User user = new User(); user.setLevel("VIP"); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(user) .apply("id IN (SELECT user_id FROM order WHERE total_amount > 10000)") // 子查询条件 .ne("level", "VIP"); // 排除已是VIP的用户 userMapper.update(null, wrapper);

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET level='VIP' WHERE id IN (SELECT user_id FROM order WHERE total_amount > 10000) AND level <> 'VIP';

‌4. 乐观锁集成‌

结合乐观锁实现安全更新‌57:

javaCopy Code
 
User user = userMapper.selectById(1); user.setName("NewName"); user.setVersion(user.getVersion()); // 传递当前版本号 UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(user) .eq("id", 1) .eq("version", user.getVersion()); // 乐观锁条件 int rows = userMapper.update(null, wrapper); if (rows == 0) { throw new OptimisticLockException("数据已被修改"); }

‌生成的 SQL‌:

sqlCopy Code
 
UPDATE user SET name='NewName', version=version+1 WHERE id=1 AND version=2; # 假设当前version=2

‌5. 动态字段控制‌

根据业务逻辑动态决定是否更新字段‌35:

javaCopy Code
 
User user = new User(); user.setEmail(request.getEmail()); boolean needUpdatePhone = StringUtils.isNotEmpty(request.getPhone()); UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.setEntity(user) .eq("id", userId) .set(needUpdatePhone, "phone", request.getPhone()) // 条件更新 .set("update_time", LocalDateTime.now()); userMapper.update(null, wrapper);

‌执行效果‌:

  • 当 request.getPhone() 非空时更新 phone 字段
  • 强制更新 update_time 字段
  • 仅当 email 非空时更新该字段

‌关键特性总结‌

功能实现方式适用场景来源
动态字段更新 setEntity() + 实体非空字段 表单提交类更新 57
SQL表达式操作 setSql() 直接编写运算逻辑 字段数值计算 35
乐观锁控制 version 字段自动检测 高并发数据安全更新 57
子查询条件 apply() 方法嵌入子查询 跨表逻辑更新 58

以上示例展示了如何通过 setEntity() 实现复杂业务需求,建议结合 Lambda 表达式和链式调用提升代码可读性‌57。

------------------------------------------------------------

 

以下为 MyBatis-Plus 中 LambdaUpdateWrapper 结合 setEntity 的详细示例及使用场景说明:


一、基础用法:通过 setEntity 绑定实体实现字段更新

javaCopy Code
 
// 创建实体对象,仅设置需更新的非空字段 User user = new User(); user.setName("李雷"); user.setAge(25); // 构建 LambdaUpdateWrapper 并绑定实体 LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper.setEntity(user) // 实体非空字段作为 SET 内容‌:ml-citation{ref="1,2" data="citationList"} .eq(User::getId, 1001); // WHERE id = 1001‌:ml-citation{ref="1" data="citationList"} userMapper.update(null, wrapper); // 第一个参数传 null

‌生成 SQL‌:

sqlCopy Code
 
UPDATE user SET name='李雷', age=25 WHERE id = 1001;

‌说明‌:setEntity 将实体中的非空字段自动填充为 SET 子句内容,避免手动逐个调用 set() 方法‌12。


二、结合动态条件实现复杂更新

javaCopy Code
 
User user = new User(); user.setStatus(2); // 更新状态为2 LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper.setEntity(user) .eq(User::getRole, "VIP") // WHERE role = 'VIP' .and(w -> w.lt(User::getScore, 60) // AND (score < 60 .or().isNull(User::getScore))); // OR score IS NULL)‌:ml-citation{ref="8" data="citationList"} userMapper.update(null, wrapper);

‌生成 SQL‌:

sqlCopy Code
 
UPDATE user SET status=2 WHERE role = 'VIP' AND (score < 60 OR score IS NULL);

‌说明‌:通过链式条件构造,支持动态组合 AND/OR 逻辑,适用于复杂业务场景‌8。


三、与 update(entity, wrapper) 结合使用

javaCopy Code
 
User user = new User(); user.setEmail("new@example.com"); LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper.gt(User::getAge, 18) // WHERE age > 18 .ne(User::getStatus, 0); // AND status != 0 userMapper.update(user, wrapper); // 实体参数传递非空字段

‌生成 SQL‌:

sqlCopy Code
 
UPDATE user SET email='new@example.com' WHERE age > 18 AND status != 0;

‌说明‌:此时 SET 子句由 user 实体的非空字段决定,wrapper 仅负责 WHERE 条件,代码更简洁‌27。


四、链式调用结合 set() 覆盖实体字段

javaCopy Code
 
User user = new User(); user.setName("韩梅梅"); LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>(); wrapper.setEntity(user) .set(User::getLoginCount, 0) // 手动覆盖 SET login_count=0‌:ml-citation{ref="6" data="citationList"} .eq(User::getId, 1002); userMapper.update(null, wrapper);

‌生成 SQL‌:

sqlCopy Code
 
UPDATE user SET name='韩梅梅', login_count=0 WHERE id = 1002;

‌说明‌:set() 方法可覆盖 setEntity 中的同名字段,实现灵活字段控制‌68。


五、Service 层封装示例

javaCopy Code
 
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { @Override public boolean updateProfile(User user) { return update( new LambdaUpdateWrapper<User>() .setEntity(user) .eq(User::getId, user.getId()) ); } }

‌调用方式‌:

javaCopy Code
 
User user = new User(); user.setId(1003); user.setAvatar("avatar.jpg"); userService.updateProfile(user);

‌说明‌:通过 Service 层封装,结合链式调用简化业务代码‌37。


关键注意事项:

  1. ‌空值处理‌:setEntity 仅包含实体中非空字段,需确保业务逻辑中空值不会误覆盖数据‌12。
  2. ‌性能优化‌:若需强制更新某字段为 null,需通过 set(字段, null) 显式指定‌6。
  3. ‌版本兼容‌:MyBatis-Plus 3.5+ 版本中 setEntity 的行为与早期版本一致,但建议测试验证‌18。
posted @ 2025-03-28 14:05  尐鱼儿  阅读(438)  评论(0)    收藏  举报