MyBatis-Plus 条件构造器详解(QueryWrapper/LambdaQueryWrapper/UpdateWrapper/LambdaUpdateWrapper)

MyBatis-Plus 提供了强大的条件构造器,用于动态构建 SQL 语句。以下是四类核心构造器的详细说明和示例:

一、QueryWrapper(普通条件构造器)

用途:构建 SELECT 查询条件 特点:使用字符串指定字段名 适用场景:字段名简单、无复杂嵌套的场景

// 示例:查询年龄大于25岁、状态为1的用户
QueryWrapper wrapper = new QueryWrapper<>();
wrapper.select("id", "name", "age")      // 指定查询字段
       .gt("age", 25)                    // age > 25
       .eq("status", 1)                  // status = 1
       .like("name", "张")               // name LIKE '%张%'
       .orderByDesc("create_time");      // 按创建时间倒序

List users = userMapper.selectList(wrapper);

生成 SQL

SELECT id, name, age 
FROM user 
WHERE age > 25 
  AND status = 1 
  AND name LIKE '%张%' 
ORDER BY create_time DESC

二、LambdaQueryWrapper(Lambda 条件构造器)

用途:构建 SELECT 查询条件 特点:使用方法引用(实体类::get方法),避免字段名硬编码 适用场景:推荐首选!字段名安全(编译期检查),重构友好

// 示例:查询邮箱不为空且状态为启用的用户
LambdaQueryWrapper lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.select(User::getId, User::getName)
             .isNotNull(User::getEmail)       // email IS NOT NULL
             .eq(User::getStatus, "ENABLED")  // status = 'ENABLED'
             .between(User::getAge, 20, 30);  // age BETWEEN 20 AND 30

List users = userMapper.selectList(lambdaWrapper);

生成 SQL

SELECT id, name 
FROM user 
WHERE email IS NOT NULL 
  AND status = 'ENABLED' 
  AND age BETWEEN 20 AND 30

三、UpdateWrapper(更新条件构造器)

用途:构建 UPDATE 操作条件 特点:支持同时设置更新字段和 WHERE 条件 适用场景:不需要实体对象参与的更新操作

// 示例:将所有VIP用户的积分增加100,状态设为2
UpdateWrapper updateWrapper = new UpdateWrapper<>();
updateWrapper.set("points", "points + 100")  // 字段自增
             .set("status", 2)               // 直接设值
             .eq("is_vip", true);            // WHERE is_vip = true

userMapper.update(null, updateWrapper);  // 第一个参数传null

生成 SQL

UPDATE user 
SET points = points + 100, 
    status = 2 
WHERE is_vip = true

四、LambdaUpdateWrapper(Lambda 更新构造器)

用途:构建 UPDATE 操作条件 特点:Lambda 表达式 + 更新操作 适用场景:安全更新字段(推荐首选)

// 示例:冻结30天未登录的用户
LambdaUpdateWrapper lambdaUpdate = new LambdaUpdateWrapper<>();
lambdaUpdate.set(User::getStatus, "FROZEN")
            .setSql("login_count = login_count + 1")  // 混合SQL
            .lt(User::getLastLoginTime, LocalDate.now().minusDays(30));

userMapper.update(null, lambdaUpdate);

生成 SQL

UPDATE user 
SET status = 'FROZEN', 
    login_count = login_count + 1 
WHERE last_login_time < '2025-07-09'

五、混合使用场景

实体对象 + Wrapper 组合更新
User user = new User();
user.setPoints(100);  // 设置更新字段

LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(User::getStatus, "ACTIVE");  // 设置条件

// 实体对象设置值 + Wrapper设置条件
userMapper.update(user, wrapper); 

生成 SQL

UPDATE user SET points = 100 WHERE status = 'ACTIVE'

六、核心对比总结

构造器 适用操作 字段指定方式 安全性 推荐场景
QueryWrapper SELECT 字符串字段名 低(运行时) 简单查询
LambdaQueryWrapper SELECT 方法引用(::) (编译时) 推荐!所有查询场景
UpdateWrapper UPDATE 字符串字段名 低(运行时) 无需实体的更新
LambdaUpdateWrapper UPDATE 方法引用(::) (编译时) 推荐!所有更新场景

最佳实践建议

  1. 优先使用 Lambda 变体 LambdaQueryWrapper/LambdaUpdateWrapper 可避免字段名拼写错误,重构更安全

  2. 复杂更新混合使用

       // 实体设值 + Wrapper条件
       new User().setName("NewName"), 
       new LambdaUpdateWrapper().eq(User::getId, 1))
  3. 动态条件技巧
   wrapper.eq(StringUtils.isNotBlank(name), User::getName, name)
  1. 慎用字符串字段名 除非处理动态字段(如字段名来自参数),否则始终优先用 Lambda 方法引用

通过合理使用条件构造器,可减少 90% 的 SQL 编写工作,同时保持代码的类型安全和可维护性。

你可能感兴趣的:(MybatisPlus,mybatis,java,后端,mysql,数据库)