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

JPA中如何基于多值列通过QueryByExample实现分页查询?

多列多值分页查询的实现方案

QueryByExample(QBE)仅支持单值/空值的匹配查询,无法直接处理多值列表的IN查询需求,以下是几种可行的实现方式:

方案一:派生查询方法(最简洁)

直接在Spring Data JPA Repository接口中定义符合命名规则的查询方法,框架会自动生成IN查询逻辑:

// PersonRepository接口
public interface PersonRepository extends JpaRepository<Person, Long> {
    Page<Person> findByFirstNameInAndLastNameIn(List<String> firstNames, List<String> lastNames, Pageable pageable);
}

调用示例:

List<String> firstNames = Arrays.asList("AName", "BName", "CName");
List<String> lastNames = Arrays.asList("xName", "yName", "zName");
Page<Person> resultPage = personRepository.findByFirstNameInAndLastNameIn(firstNames, lastNames, PageRequest.of(0, 10));

方案二:自定义JPQL查询(适合复杂固定条件)

通过@Query注解编写JPQL语句,精准控制查询逻辑,适合需要和其他固定过滤条件组合的场景:

// PersonRepository接口
public interface PersonRepository extends JpaRepository<Person, Long> {
    @Query("SELECT p FROM Person p WHERE p.firstName IN :firstNames AND p.lastName IN :lastNames")
    Page<Person> findByMultiNames(@Param("firstNames") List<String> firstNames, 
                                 @Param("lastNames") List<String> lastNames, 
                                 Pageable pageable);
}

调用方式与方案一一致。

方案三:Specification动态查询(适合动态多条件)

如果查询条件是动态变化的(比如需根据前端参数动态添加年龄、婚姻状态等过滤规则),可以使用Specification构建灵活的动态查询:

首先让Repository继承JpaSpecificationExecutor:

public interface PersonRepository extends JpaRepository<Person, Long>, JpaSpecificationExecutor<Person> {
}

然后构建查询条件并执行分页:

List<String> firstNames = Arrays.asList("AName", "BName", "CName");
List<String> lastNames = Arrays.asList("xName", "yName", "zName");

Specification<Person> querySpec = (root, query, criteriaBuilder) -> {
    Predicate firstNameIn = root.get("firstName").in(firstNames);
    Predicate lastNameIn = root.get("lastName").in(lastNames);
    // 可按需追加其他条件,例如:
    // Predicate agePredicate = criteriaBuilder.greaterThan(root.get("age"), 18);
    // return criteriaBuilder.and(firstNameIn, lastNameIn, agePredicate);
    return criteriaBuilder.and(firstNameIn, lastNameIn);
};

Page<Person> resultPage = personRepository.findAll(querySpec, PageRequest.of(0, 10));

补充说明

QueryByExample的设计定位是快速实现单值匹配的简单查询,不支持集合类型的IN查询,因此上述三种方案是更适配需求的选择,可根据实际场景(固定/动态条件、复杂度)灵活选用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 20:57:03