lambdaQueryWrapper多条件嵌套查询方法是什么

发布时间:2022-01-11 11:15:16 作者:iii
来源:亿速云 阅读:2065
# LambdaQueryWrapper多条件嵌套查询方法详解

## 1. 引言

在MyBatis-Plus框架中,`LambdaQueryWrapper`是一个强大的查询条件构造器,它允许开发者以Lambda表达式的方式构建类型安全的查询条件。相比传统的字符串拼接方式,`LambdaQueryWrapper`提供了更优雅、更安全的查询条件构建方法。本文将深入探讨`LambdaQueryWrapper`的多条件嵌套查询方法,帮助开发者掌握复杂查询场景下的使用技巧。

## 2. LambdaQueryWrapper基础

### 2.1 基本概念

`LambdaQueryWrapper`是MyBatis-Plus提供的一个查询条件包装器,它通过Lambda表达式引用实体类的属性,避免了硬编码字段名的风险。主要特点包括:

- 类型安全:编译时检查属性名是否正确
- 代码智能提示:IDE能提供属性名的自动补全
- 链式调用:支持流畅的API设计

### 2.2 基本使用方法

```java
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getName, "张三")
       .gt(User::getAge, 18)
       .orderByDesc(User::getCreateTime);
List<User> users = userMapper.selectList(wrapper);

3. 多条件查询基础

3.1 AND条件连接

默认情况下,多个条件是通过AND连接的:

wrapper.eq(User::getDepartment, "研发部")
       .ge(User::getSalary, 10000);

对应的SQL:WHERE department = '研发部' AND salary >= 10000

3.2 OR条件连接

使用or()方法可以实现OR条件连接:

wrapper.eq(User::getDepartment, "研发部")
       .or()
       .eq(User::getDepartment, "市场部");

对应的SQL:WHERE department = '研发部' OR department = '市场部'

4. 嵌套查询方法

4.1 嵌套AND条件

当需要构建更复杂的条件时,可以使用嵌套查询。例如,查询年龄大于30或者(名字包含”张”并且工资小于5000)的员工:

wrapper.gt(User::getAge, 30)
       .or(w -> w.like(User::getName, "张")
                 .lt(User::getSalary, 5000));

对应的SQL:WHERE age > 30 OR (name LIKE '%张%' AND salary < 5000)

4.2 嵌套OR条件

同样可以嵌套OR条件:

wrapper.eq(User::getStatus, 1)
       .and(w -> w.gt(User::getAge, 25)
                  .or()
                  .lt(User::getSalary, 8000));

对应的SQL:WHERE status = 1 AND (age > 25 OR salary < 8000)

4.3 多级嵌套

可以构建更复杂的多级嵌套条件:

wrapper.and(w1 -> w1.eq(User::getType, 1)
                    .or()
                    .eq(User::getType, 2))
       .or(w2 -> w2.like(User::getName, "admin")
                    .and(w3 -> w3.isNotNull(User::getEmail)
                               .eq(User::getStatus, 1)));

对应的SQL:

WHERE (type = 1 OR type = 2) 
OR (name LIKE '%admin%' AND (email IS NOT NULL AND status = 1))

5. 常用嵌套查询场景

5.1 范围查询组合

wrapper.and(w -> w.between(User::getAge, 20, 30)
                 .or()
                 .between(User::getAge, 40, 50));

5.2 多字段模糊查询

wrapper.and(w -> w.like(User::getName, "张")
                 .or()
                 .like(User::getNickname, "张"));

5.3 条件分组

wrapper.eq(User::getCompany, "ABC公司")
       .and(w -> w.gt(User::getWorkYears, 3)
                  .or()
                  .eq(User::getEducation, "硕士"));

6. 动态条件嵌套

6.1 根据参数动态构建条件

public List<User> queryUsers(String name, Integer minAge, Integer maxAge) {
    LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
    wrapper.eq(StringUtils.isNotBlank(name), User::getName, name)
           .and(w -> w.ge(minAge != null, User::getAge, minAge)
                      .le(maxAge != null, User::getAge, maxAge));
    return userMapper.selectList(wrapper);
}

6.2 复杂动态条件

wrapper.nested(w -> {
    if (condition1) {
        w.eq(User::getField1, value1);
    }
    if (condition2) {
        w.or().eq(User::getField2, value2);
    }
});

7. 性能优化建议

7.1 避免过度嵌套

虽然嵌套查询很强大,但过度嵌套会导致SQL复杂,影响性能。建议: - 嵌套层级不超过3层 - 复杂的业务逻辑考虑拆分成多个查询

7.2 索引友好设计

确保嵌套条件中的字段有适当的索引: - 等值查询字段优先 - 范围查询字段放在后面

7.3 条件顺序优化

将高选择性的条件放在前面,可以更快过滤数据:

wrapper.eq(User::getId, 123)  // 高选择性条件
       .and(w -> w.like(User::getName, "%张%"));

8. 实际应用案例

8.1 用户高级搜索

public List<User> advancedSearch(UserQuery query) {
    return lambdaQuery()
        .eq(query.getDeptId() != null, User::getDeptId, query.getDeptId())
        .and(w -> w.like(StringUtils.isNotBlank(query.getKeyword()), 
                    User::getName, query.getKeyword())
                  .or()
                  .like(StringUtils.isNotBlank(query.getKeyword()), 
                    User::getMobile, query.getKeyword()))
        .between(query.getStartTime() != null && query.getEndTime() != null, 
                User::getCreateTime, query.getStartTime(), query.getEndTime())
        .orderByDesc(User::getCreateTime)
        .list();
}

8.2 权限过滤查询

public List<Order> queryOrdersWithPermission(Long userId) {
    return lambdaQuery()
        .eq(Order::getStatus, 1)
        .and(w -> w.eq(Order::getUserId, userId)
                  .or()
                  .inSql(Order::getDeptId, 
                         "SELECT dept_id FROM user_dept WHERE user_id = " + userId))
        .list();
}

9. 常见问题与解决方案

9.1 嵌套条件不生效

可能原因: 1. 条件逻辑错误 2. 使用了错误的连接方式

解决方案:

// 错误示例
wrapper.or(w -> w.eq(User::getA, 1))
      .eq(User::getB, 2);  // 此条件会在OR之外

// 正确写法
wrapper.or(w -> w.eq(User::getA, 1)
                .eq(User::getB, 2));

9.2 条件顺序不符合预期

使用括号明确优先级:

wrapper.and(w -> w.eq(User::getA, 1)
                 .or()
                 .eq(User::getB, 2))
      .eq(User::getC, 3);

9.3 动态条件处理

使用nested方法处理复杂动态条件:

wrapper.nested(w -> {
    if (conditionA) {
        w.eq(User::getA, 1);
    }
    if (conditionB) {
        w.or().eq(User::getB, 2);
    }
});

10. 总结

LambdaQueryWrapper的多条件嵌套查询为复杂业务场景提供了强大的支持。通过本文的介绍,我们了解了:

  1. 基本的AND/OR条件连接方法
  2. 单层和多层嵌套查询的构建技巧
  3. 动态条件组合的最佳实践
  4. 性能优化和常见问题解决方案

掌握这些技巧后,开发者能够更加灵活地构建各种复杂查询,同时保持代码的类型安全和可维护性。在实际项目中,应根据具体业务需求合理选择查询构建方式,避免过度复杂的嵌套查询影响性能。

附录:LambdaQueryWrapper常用方法速查表

方法名 描述 示例
eq 等于 eq(User::getName, "张三")
ne 不等于 ne(User::getStatus, 0)
gt 大于 gt(User::getAge, 18)
ge 大于等于 ge(User::getScore, 60)
lt 小于 lt(User::getSalary, 10000)
le 小于等于 le(User::getLevel, 5)
between 介于 between(User::getAge, 20, 30)
like 模糊匹配 like(User::getName, "%张%")
in IN查询 in(User::getId, ids)
and AND嵌套 and(w -> w.eq(...))
or OR嵌套 or(w -> w.eq(...))
nested 复杂嵌套 nested(w -> {...})

”`

推荐阅读:
  1. 第3课 python条件判断与条件嵌套
  2. 怎么在python条件if里嵌套多一个if

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

lambdaquerywrapper

上一篇:如何实现J2SE入门

下一篇:MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决方法是什么

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》