You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写单条数据库查询支持多日期条件、分页及可选参数筛选

单条查询实现多时间规则+可选用户筛选的分页查询

需求规则

需要通过单条查询语句覆盖所有查询逻辑,无需拆分多套SQL:

  • 当startDate、endDate均不为空:查询时间落在两者区间内的记录,支持分页
  • 当startDate为空、endDate不为空:查询时间早于endDate的记录,支持分页
  • 当startDate不为空、endDate为空:查询时间晚于startDate的记录,支持分页
  • 额外支持userIdentifier可选筛选:参数为空时不做用户维度过滤,传值时仅匹配对应用户的记录

原有初始代码

已编写的初始查询仅判断了userIdentifier为空的场景,缺失时间过滤、分页、用户传值匹配逻辑,代码如下:

@Query("SELECT m FROM notification m WHERE :userIdentifier is null")
Flux<Notification> findAllByUserIdentifier(Timestamp startDate, Timestamp endDate, int page, 
int size);

实现代码

直接通过布尔逻辑组合所有分支条件即可,单条JPQL即可覆盖所有场景,分页建议直接使用Spring Data原生的Pageable参数,无需手动传递page、size计算偏移:

@Query("SELECT m FROM Notification m " +
       "WHERE (:userIdentifier IS NULL OR m.userIdentifier = :userIdentifier) " +
       "AND ( " +
       "  (:startDate IS NOT NULL AND :endDate IS NOT NULL AND m.createTime BETWEEN :startDate AND :endDate) " +
       "  OR (:startDate IS NULL AND :endDate IS NOT NULL AND m.createTime <= :endDate) " +
       "  OR (:startDate IS NOT NULL AND :endDate IS NULL AND m.createTime >= :startDate) " +
       "  OR (:startDate IS NULL AND :endDate IS NULL) " +
       ") ")
Flux<Notification> findAllByCondition(
        @Param("userIdentifier") String userIdentifier,
        @Param("startDate") Timestamp startDate,
        @Param("endDate") Timestamp endDate,
        Pageable pageable
);

逻辑说明

所有条件通过OR分支匹配对应参数场景,不会出现逻辑冲突:

  1. 用户筛选逻辑:userIdentifier传null时条件直接成立不做过滤,传值时仅匹配字段值等于入参的记录
  2. 时间筛选逻辑:完全对齐需求规则,额外覆盖了两个时间参数都为空的场景(此时不做时间范围过滤,查询全量符合用户条件的记录)

注意:如果你的实体类中存储时间的字段名不是createTime,替换为实际字段名即可;响应式Spring Data场景下Pageable参数可被正常识别,自动完成分页逻辑。

内容的提问来源于stack exchange,提问作者Volatail

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 16:45:15