[toc]
| 单词 | 词性 | 音标 | 含义 |
|---|---|---|---|
| Update | v. | /ˌʌpˈdeɪt/ | 更新(UpdateWrapper 是封装更新条件的包装器,可同时指定要更新的列和条件) |
| Set | v. | /set/ | 设置(set 方法指定要把哪个列改成什么值) |
| Sql | n. | /es kjuː ˈel/ | SQL(setSql 方法直接拼一段 SQL 片段到 SET 部分) |
Lecture08-更新操作-UpdateWrapper
一、什么时候需要 UpdateWrapper
第 4 章的 updateById 用法:先查出来,改实体属性,再整体更新。它的问题:
- 必须先查出完整对象,再修改,多一次查询
- 如果只改 1~2 个字段,把整个对象都 SET 一遍,显得笨重
实际开发中更常见的需求是「直接把某几列改成新值」,不关心其他列。这正是 UpdateWrapper 的用武之地。
二、核心用法
1、update(entity, wrapper):按条件更新
需要导入:
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
@Test
public void testUpdateByWrapper() {
// 要改的值:封装在实体对象里(null 字段不参与 SET)
Employee employee = new Employee();
employee.setEmpSalary(new BigDecimal("20000.00"));
// 更新条件:emp_no = 'No.10004'
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getEmpNo, "No.10004");
int rows = employeeMapper.update(employee, wrapper);
System.out.println("rows = " + rows);
}
==> Preparing: UPDATE t_emp SET emp_salary=? WHERE emp_no=?
==> Parameters: 20000.00(BigDecimal), No.10004(String)
要点:
- 第一个参数
entity:提供要修改的值(非 null 字段参与 SET) - 第二个参数
wrapper:提供更新条件(WHERE) - 只更新了
emp_salary一列,其他列完全不动
2、set(列, 值):不用实体,直接指定列
如果不想创建实体对象,可以用 set 方法直接在 wrapper 里写:
@Test
public void testUpdateSet() {
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getEmpNo, "No.10004")
.set(Employee::getEmpSalary, new BigDecimal("21000.00")) // 设置要改的列
.set(Employee::getDeptId, 1); // 可以连续 set 多列
// 第一个参数传 null:不提供实体,值全在 wrapper 的 set 里
int rows = employeeMapper.update(null, wrapper);
System.out.println("rows = " + rows);
}
==> Preparing: UPDATE t_emp SET emp_salary=?,dept_id=? WHERE emp_no=?
==> Parameters: 21000.00(BigDecimal), 1(Integer), No.10004(String)
update(null, wrapper)是固定搭配:实体为 null,全靠 wrapper 的set提供值。
3、setSql:拼一段 SQL 片段
需要「在原来值的基础上计算」时(比如工资上涨 10%),用 setSql:
@Test
public void testUpdateSetSql() {
LambdaUpdateWrapper<Employee> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(Employee::getDeptId, 1)
.setSql("emp_salary = emp_salary * 1.1"); // 部门 1 全员涨薪 10%
int rows = employeeMapper.update(null, wrapper);
System.out.println("rows = " + rows);
}
==> Preparing: UPDATE t_emp SET emp_salary = emp_salary * 1.1 WHERE dept_id=?
setSql的参数会原样拼进 SQL,只写自己控制的常量或列名,不要拼接用户输入。
三、UpdateWrapper 与 updateById 如何选择
| 场景 | 推荐写法 |
|---|---|
| 前端提交了整个表单,要更新多个字段 | updateById(entity)(先查后改或直接用表单对象) |
| 只更新 1~2 个字段(如改密码、改状态、涨工资) | update(entity, wrapper) 或 set(...) 局部更新 |
| 按非主键条件批量更新 | update(null, wrapper) |
基于原值计算(如 +1、*1.1) | setSql(...) |
一般原则:能用 updateById 的场景优先 updateById;只改个别列、或者条件不是主键时,用 UpdateWrapper。
四、LambdaUpdateWrapper 与 UpdateWrapper 家族的关系
与查询端一样,更新端也有两套:UpdateWrapper(字符串列名)和 LambdaUpdateWrapper(方法引用)。同 QueryWrapper 家族的理由,推荐直接用 LambdaUpdateWrapper。
条件方法与查询端通用:eq / ne / gt / ge / lt / le / between / in / like / isNull / orderBy / last 等,全部支持。
五、本章小结
update(entity, wrapper):实体提供值,wrapper 提供条件set(列, 值):直接在 wrapper 里指定要改的列,可连续 setsetSql(...):基于原值计算等特殊场景- 与
updateById的选择:改个别字段、条件非主键 → UpdateWrapper - 推荐用
LambdaUpdateWrapper,方法引用更安全
下一章学习逻辑删除与字段自动填充,让删除"不真删"、时间字段自动维护。