QueryWrapper中or的使用技巧分享

 更新时间:2024年10月22日 09:26:57   作者:Kwan的解忧杂货铺  
在日常的开发工作中,处理数据库查询是一个非常常见的任务,尤其是当我们需要在复杂条件下筛选数据时,如何编写高效、简洁且可维护的查询逻辑显得尤为重要,本文给大家介绍了QueryWrapper中or的使用技巧,需要的朋友可以参考下

场景描述

假设我们正在开发一个邮件系统,系统中有一个名为 MailInfo 的表,用于存储邮件信息。该表有两个字段与用户相关:user_id 表示邮件的发送者,to_user_id 表示邮件的接收者。我们需要编写一个查询,找出当前用户(userId)所有与其相关的邮件,不论是他发送的,还是接收到的。此外,我们还要确保这些邮件未被删除,并且按更新时间进行排序。

需求拆解

根据上述需求,我们需要实现以下几点:

  • 过滤掉已删除的邮件(即 is_delete = 0)。
  • 查询条件包括 user_id 或 to_user_id 等于当前用户 ID。
  • 按照更新时间(update_time)降序排序结果,以确保最新的邮件显示在前面。

这些需求在 SQL 中可以通过一个简单的 SELECT 语句来实现,类似于:

SELECT * FROM MailInfo
WHERE is_delete = 0
AND (user_id = ? OR to_user_id = ?)
ORDER BY update_time DESC;

但在 Java 开发中,尤其是使用了 MyBatis-Plus 这样一个 ORM 框架时,我们通常会使用 QueryWrapper 来构造查询条件,以提高代码的可读性和可维护性。

使用 MyBatis-Plus 构建查询条件

在 MyBatis-Plus 中,QueryWrapper 是一个非常强大的查询构造器,它可以通过流式 API 来动态地构造 SQL 查询。在处理复杂查询条件时,例如 OR 和 AND 的组合,它也提供了相应的接口来满足需求。

下面我们来看一个具体的代码示例,展示如何通过 QueryWrapper 来构建我们的查询条件:

Page<MailInfo> pageParm = new Page<>();
pageParm.setCurrent(page);
pageParm.setSize(pageSize);
QueryWrapper<MailInfo> wrapper = new QueryWrapper<>();
wrapper.eq("is_delete", 0)  // 只查询未删除的邮件
       .and(w -> w.eq("user_id", userId).or().eq("to_user_id", userId))  // 查询当前用户发送或接收的邮件
       .orderByDesc("update_time");  // 按更新时间降序排序

return Result.ok(MailInfoDTO.Converter.INSTANCE.from(this.mailInfoService.page(pageParm, wrapper)));

代码解析

1. 分页参数

Page<MailInfo> pageParm = new Page<>();
pageParm.setCurrent(page);
pageParm.setSize(pageSize);

在大多数业务场景中,我们会对查询结果进行分页处理,以避免一次性返回过多数据,影响性能。MyBatis-Plus 提供了 Page 类来处理分页逻辑。在这段代码中,我们通过 setCurrent 方法设置当前页数,并通过 setSize 设置每页返回的记录数量。

2. 构造查询条件

QueryWrapper<MailInfo> wrapper = new QueryWrapper<>();
wrapper.eq("is_delete", 0)
       .and(w -> w.eq("user_id", userId).or().eq("to_user_id", userId));

这里的 QueryWrapper 是 MyBatis-Plus 提供的查询构造器,允许我们通过流式的方式来构造查询条件。

  • eq("is_delete", 0):添加一个 is_delete = 0 的条件,确保只查询未被标记为删除的邮件。
  • and(w -> w.eq("user_id", userId).or().eq("to_user_id", userId)):这是查询条件的核心部分。我们通过 and 方法组合多个条件,使用 Lambda 表达式 w 作为内部查询条件的参数。在 Lambda 表达式内部,先通过 eq("user_id", userId) 查询发送者为当前用户的邮件,再通过 or().eq("to_user_id", userId) 查询接收者为当前用户的邮件。通过这种方式,查询结果将包含所有与当前用户相关的邮件记录。

3. 排序条件

wrapper.orderByDesc("update_time");

这行代码用于指定排序条件。我们希望按邮件的更新时间从新到旧进行排序,因此使用了 orderByDesc 方法,并将 update_time 作为排序字段。

结果封装

在实际的开发过程中,我们通常会将查询结果封装为一个统一的返回结构。在这个例子中,我们将查询结果封装为 Result.ok,并通过 MailInfoDTO.Converter.INSTANCE 进行数据转换,将数据库实体类 MailInfo 转换为 MailInfoDTO。

QueryWrapper 的 or 使用技巧

在使用 QueryWrapper 构建查询时,or 方法是一个非常有用的工具。它允许我们在查询中添加多个可能的条件,从而使查询结果更加灵活。在本文的例子中,我们使用了 or 来查询 user_id 或 to_user_id 等于 userId 的记录,从而满足了业务需求。

但是,使用 or 也需要小心,因为它可能会影响查询的性能。在涉及大量数据时,OR 条件的查询速度可能会较慢。为此,我们可以考虑以下优化策略:

  1. 创建索引:确保 user_id 和 to_user_id 字段上创建了索引,这样可以大幅提高查询速度。
  2. 使用缓存:在高频率访问的场景下,适当地使用缓存可以减少数据库查询次数,提升系统的整体性能。
  3. 分表设计:如果 MailInfo 表的数据量非常大,可以考虑通过分表来降低单个表的查询压力。

到此这篇关于QueryWrapper中or的使用技巧分享的文章就介绍到这了,更多相关QueryWrapper or使用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java多线程编程之线程的生命周期

    java多线程编程之线程的生命周期

    线程要经历开始(等待)、运行、挂起和停止四种不同的状态。这四种状态都可以通过Thread类中的方法进行控制。下面给出了Thread类中和这四种状态相关的方法
    2014-01-01
  • Java协议字节操作工具类详情

    Java协议字节操作工具类详情

    这篇文章主要介绍了Java协议字节操作工具类详情,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • java收集器Collector案例汇总

    java收集器Collector案例汇总

    这篇文章主要介绍了java收集器Collector案例汇总,Collectors作为Stream的collect方法的参数,Collector是一个接口,它是一个可变的汇聚操作,更多相关介绍,需要的朋友可以参考下
    2022-06-06
  • 使用多个servlet时Spring security需要指明路由匹配策略问题

    使用多个servlet时Spring security需要指明路由匹配策略问题

    这篇文章主要介绍了使用多个servlet时Spring security需要指明路由匹配策略问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • Java实现九九乘法表的完整实例(对齐版)

    Java实现九九乘法表的完整实例(对齐版)

    这篇文章主要给大家介绍了关于Java实现九九乘法表(对齐版)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-12-12
  • java如何获取两个List集合之间的交集、差集、并集

    java如何获取两个List集合之间的交集、差集、并集

    在日常开发中经常会遇到对2个集合的操作,例如2个集合之间取相同的元素(交集),2个集合之间取不相同的元素(差集)等等,这篇文章主要给大家介绍了关于java如何获取两个List集合之间的交集、差集、并集的相关资料,需要的朋友可以参考下
    2024-02-02
  • 全面解读Java编程中的内部类

    全面解读Java编程中的内部类

    这篇文章主要介绍了Java的内部类,包括类成员访问等Java入门学习中的基础知识,需要的朋友可以参考下
    2015-09-09
  • java 数据结构中栈和队列的实例详解

    java 数据结构中栈和队列的实例详解

    这篇文章主要介绍了java 数据结构中栈和队列的实例详解的相关资料,主要使用数组与线性表的方法来实现,需要的朋友可以参考下
    2017-09-09
  • Java8 Stream flatmap中间操作用法解析

    Java8 Stream flatmap中间操作用法解析

    这篇文章主要介绍了Java8 Stream flatmap中间操作用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-07-07
  • MyBatis批量插入的五种方式

    MyBatis批量插入的五种方式

    这篇文章主要介绍了MyBatis批量插入的五种方式,每种方式结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-11-11

最新评论