Lecture08-更新操作-UpdateWrapper

文章目录

    [toc]

    单词词性音标含义
    Updatev./ˌʌpˈdeɪt/更新(UpdateWrapper 是封装更新条件的包装器,可同时指定要更新的列和条件)
    Setv./set/设置(set 方法指定要把哪个列改成什么值)
    Sqln./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 里指定要改的列,可连续 set
    • setSql(...):基于原值计算等特殊场景
    • 与 updateById 的选择:改个别字段、条件非主键 → UpdateWrapper
    • 推荐用 LambdaUpdateWrapper,方法引用更安全

    下一章学习逻辑删除与字段自动填充,让删除"不真删"、时间字段自动维护。

    end