deepseek回答MyBatis-Plus UpdateWrapper setEntity() 示例代码
以下是 MyBatis-Plus 中 UpdateWrapper 结合 setEntity() 的示例代码及详细说明,适用于不同场景的更新操作:
1. 基础用法:更新实体中的非空字段
将实体对象中的非空字段作为更新内容,结合条件更新指定记录。
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:
UPDATE user SET name='John', age=25 WHERE id=1; 说明:
setEntity()会自动提取实体对象中 非空字段 作为更新内容。email字段因值为null被忽略。
2. 动态更新:仅更新提交的非空字段
结合业务逻辑动态更新部分字段(如用户修改个人信息)。
// 假设前端提交的修改数据(部分字段可能为空) 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:
UPDATE user SET name='Alice', email='' WHERE id=1001; 说明:
email字段被更新为空字符串(非null值)。- 若字段值为
null(如userParam.setEmail(null)),则不会更新。
3. 强制更新 null 字段
通过配置全局策略或使用 set() 方法强制更新 null 值。
方案1:全局配置(忽略 null 改为更新 null)
# application.yml mybatis-plus: global-config: db-config: update-strategy: not_empty # 默认忽略 null,此处改为非空更新(根据需求调整) 方案2:使用 set() 显式覆盖
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:
UPDATE user SET name=null WHERE id=1; 4. 与 set() 方法联用(优先级控制)
当同时使用 setEntity() 和 set() 时,set() 优先级更高。
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:
UPDATE user SET name='Bob', age=40 WHERE id=1; # age=40 覆盖了实体的 age=30 5. 复杂条件组合
结合 and()、or() 等条件构造复杂更新逻辑。
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:
UPDATE user SET status=1, remark='特殊用户' WHERE role='admin' AND (age < 18 OR score > 90); 6. 批量更新
结合 in() 条件实现批量更新。
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:
UPDATE user SET is_deleted=1 WHERE id IN (1001, 1002, 1003); 注意事项
- 字段覆盖规则:
set()方法优先级高于setEntity()。 - 空值处理:默认忽略
null字段,需通过全局配置或显式set()更新null。 - 性能优化:避免全表更新,始终附加有效条件(如
eq("id", value))。 - Lambda 安全:推荐使用
LambdaUpdateWrapper避免字段名硬编码:javaCopy CodeLambdaUpdateWrapper<User> wrapper = Wrappers.lambdaUpdate(); wrapper.eq(User::getId, 1) .set(User::getName, "Tom");
通过 setEntity() 可以简化基于实体对象的动态更新操作,结合条件构造器实现灵活的业务需求。
------------------------------------------------------------
以下是结合 MyBatis-Plus setEntity() 方法的复杂场景示例代码,涵盖多种业务场景并综合多个技术实现方案:
1. 动态更新部分字段 + 复杂条件组合
通过实体对象动态更新非空字段,并结合多重嵌套条件筛选目标数据57:
// 实体对象:仅更新非空字段 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:
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:
// 更新所有部门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:
UPDATE user SET bonus=500, salary = salary + 1000 WHERE dept_id IN (100,101,102) AND hire_date <= '2020-01-01'; 3. 联表更新模拟
通过子查询实现类联表更新效果(需数据库支持)58:
// 根据订单表更新用户等级 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:
UPDATE user SET level='VIP' WHERE id IN (SELECT user_id FROM order WHERE total_amount > 10000) AND level <> 'VIP'; 4. 乐观锁集成
结合乐观锁实现安全更新57:
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:
UPDATE user SET name='NewName', version=version+1 WHERE id=1 AND version=2; # 假设当前version=2 5. 动态字段控制
根据业务逻辑动态决定是否更新字段35:
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 绑定实体实现字段更新
// 创建实体对象,仅设置需更新的非空字段 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:
UPDATE user SET name='李雷', age=25 WHERE id = 1001; 说明:setEntity 将实体中的非空字段自动填充为 SET 子句内容,避免手动逐个调用 set() 方法12。
二、结合动态条件实现复杂更新
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:
UPDATE user SET status=2 WHERE role = 'VIP' AND (score < 60 OR score IS NULL); 说明:通过链式条件构造,支持动态组合 AND/OR 逻辑,适用于复杂业务场景8。
三、与 update(entity, wrapper) 结合使用
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:
UPDATE user SET email='new@example.com' WHERE age > 18 AND status != 0; 说明:此时 SET 子句由 user 实体的非空字段决定,wrapper 仅负责 WHERE 条件,代码更简洁27。
四、链式调用结合 set() 覆盖实体字段
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:
UPDATE user SET name='韩梅梅', login_count=0 WHERE id = 1002; 说明:set() 方法可覆盖 setEntity 中的同名字段,实现灵活字段控制68。
五、Service 层封装示例
调用方式:
User user = new User(); user.setId(1003); user.setAvatar("avatar.jpg"); userService.updateProfile(user); 说明:通过 Service 层封装,结合链式调用简化业务代码37。
关键注意事项:
- 空值处理:
setEntity仅包含实体中非空字段,需确保业务逻辑中空值不会误覆盖数据12。 - 性能优化:若需强制更新某字段为
null,需通过set(字段, null)显式指定6。 - 版本兼容:MyBatis-Plus 3.5+ 版本中
setEntity的行为与早期版本一致,但建议测试验证18。

浙公网安备 33010602011771号