MyBatis-Plus查询构造器详解:LambdaQueryWrapper与QueryWrapper对比指南

MyBatis-Plus作为MyBatis的增强工具,提供了强大的查询构造器功能。其中LambdaQueryWrapperQueryWrapper是最常用的两种查询条件封装方式。本文将深入解析它们的用法,并通过实际案例展示如何选择最适合的查询构造器。

一、QueryWrapper:传统条件构造器

1. 基本用法

QueryWrapper是MyBatis-Plus最早提供的条件构造器,通过字符串指定字段名:

QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name", "张三")
       .between("age", 20, 30)
       .like("email", "@example.com");

2. 常用API方法

方法名说明示例
eq等于 =eq("name", "张三")
ne不等于 !=ne("status", 0)
gt大于 >gt("age", 18)
ge大于等于 >=ge("score", 60)
lt小于 <lt("create_time", LocalDateTime.now())
le小于等于 <=le("balance", 1000)
betweenBETWEEN 值1 AND 值2between("age", 18, 30)
likeLIKE '%值%'like("name", "张")
orderByAsc升序排序orderByAsc("create_time")

3. 复杂查询示例

// 多条件组合查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.select("id", "name", "age")
      .eq("dept_id", 2)
      .and(qw -> qw.gt("age", 20).or().isNotNull("email"))
      .orderByDesc("create_time");

List<User> users = userMapper.selectList(wrapper);

二、LambdaQueryWrapper:类型安全条件构造器

1. 基本用法

LambdaQueryWrapper通过方法引用指定字段,避免字符串硬编码:

LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
       .between(User::getAge, 20, 30)
       .like(User::getEmail, "@example.com");

2. 核心优势

  • ​类型安全​​:编译时检查字段名是否正确
  • ​IDE支持​​:自动补全和方法跳转
  • ​重构友好​​:字段名修改自动同步到查询条件
  • ​代码可读性​​:更接近自然语言的表达方式

3. 复杂查询示例

// 嵌套查询+多条件组合
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.select(User::getId, User::getName, User::getAge)
      .eq(User::getDeptId, 2)
      .nested(qw -> qw.gt(User::getAge, 20).or().isNotNull(User::getEmail))
      .orderByDesc(User::getCreateTime);

List<User> users = userMapper.selectList(wrapper);

三、LambdaQueryWrapper与QueryWrapper对比

1. 语法对比

特性LambdaQueryWrapperQueryWrapper
​字段引用方式​方法引用 (User::getName)字符串 ("name")
​编译时检查​✅ 字段名错误直接编译失败❌ 运行时才能发现错误
​IDE支持​✅ 自动补全、方法跳转❌ 纯字符串无提示
​重构安全性​✅ 字段重命名自动更新❌ 需手动修改字符串
​复杂条件可读性​⭐⭐⭐⭐⭐⭐⭐

2. 性能对比

  • ​编译阶段​​:LambdaQueryWrapper有轻微反射开销(仅首次)
  • ​运行时​​:两者生成的SQL完全相同,性能无差异
  • ​内存占用​​:基本一致

3. 适用场景对比

场景LambdaQueryWrapperQueryWrapper
固定字段条件查询✅ 推荐⚠️ 可用
动态字段名查询❌ 不适用✅ 必须
多表复杂关联查询⚠️ 部分支持✅ 更灵活
需要高可读性的项目✅ 首选❌ 不推荐
维护历史遗留代码❌ 可能不兼容✅ 兼容

四、最佳实践建议

1. 优先使用LambdaQueryWrapper的情况

// 1. 简单条件查询
lambdaWrapper.eq(User::getStatus, 1);

// 2. 多条件组合
lambdaWrapper.gt(User::getScore, 90)
             .le(User::getAge, 30);

// 3. 嵌套查询
lambdaWrapper.nested(qw -> 
    qw.eq(User::getType, 1).or().eq(User::getType, 2)
);

2. 必须使用QueryWrapper的情况

// 1. 动态字段名查询
String fieldName = isNewVersion ? "new_name" : "name";
queryWrapper.eq(fieldName, "张三");

// 2. 数据库函数使用
queryWrapper.apply("date_format(create_time,'%Y-%m')={0}", "2023-01");

// 3. 复杂SQL片段
queryWrapper.exists("select 1 from dept where dept.id=user.dept_id and dept.status=1");

3. 混合使用技巧

// 在LambdaQueryWrapper中嵌入QueryWrapper
LambdaQueryWrapper<User> lambdaWrapper = new LambdaQueryWrapper<>();
lambdaWrapper.and(qw -> {
    QueryWrapper<User> query = new QueryWrapper<>();
    query.apply("(score > 80 or honor_count > 5)");
    return qw.add(query);
});

五、高级用法示例

1. 条件优先级控制

// 使用括号明确优先级
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getDeptId, 2)
       .and(qw -> qw.gt(User::getAge, 25).or().eq(User::getTitle, "经理"));
// 生成SQL: dept_id = 2 AND (age > 25 OR title = '经理')

2. 链式调用优化

// 使用静态导入简化代码
import static com.baomidou.mybatisplus.core.toolkit.Wrappers.*;

List<User> users = userMapper.selectList(
    lambdaQuery(User.class)
        .eq(User::getName, "张三")
        .gt(User::getAge, 18)
        .list()
);

3. 批量查询构建

// 构建批量更新条件
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.in(User::getId, Arrays.asList(1, 2, 3))
       .set(User::getStatus, 1)
       .set(User::getUpdateTime, LocalDateTime.now());

userMapper.update(null, wrapper);

六、总结与选择建议

  1. ​新项目开发​​:优先使用LambdaQueryWrapper,享受类型安全和代码可读性优势
  2. ​动态字段场景​​:必须使用QueryWrapper处理运行时确定的字段名
  3. ​复杂SQL​​:QueryWrapper对原生SQL支持更好
  4. ​团队协作​​:统一代码风格,避免混用造成混乱

​终极建议​​:在保证功能实现的前提下,尽可能使用LambdaQueryWrapper,只在必要场景下使用QueryWrapper。两者配合使用可以发挥MyBatis-Plus最大的查询能力。

通过合理选择查询构造器,可以显著提升代码质量、开发效率和系统可维护性。希望本文能帮助您在项目中做出更明智的技术选型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值