以下是 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 中 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。