Spring JPA如何实现去重、非空且排序的多列数据查询?
错误原因分析
- 方法名查询报错:你将需要去重的
CarNumber、CarName字段写在了方法名By关键字之后的查询条件段,Spring Data JPA会默认把By后跟随的每一个字段解析为需要传入参数的查询条件,因此会提示缺少入参。方法名中的Distinct是作用于返回结果的去重规则,不需要把去重字段放到By之后。 - @Query写法报错:首先注解内的查询语句没有用引号包裹属于语法错误,其次你只查询
carNumber、carName两个字段,无法直接映射到完整的Car实体对象,会出现类型匹配问题。
正确实现方案
方案1:@Query注解实现(推荐,精准匹配你的SQL需求)
该方式可以精准实现仅针对两列去重的逻辑,首先需要在你的Car实体类中新增匹配返回字段的构造方法:
// 替换为你实际的包路径、字段类型 public Car(String carNumber, String carName) { this.carNumber = carNumber; this.carName = carName; // 其他未查询的字段可以按需赋默认值 }
Repository层写法如下:
// 注意语句用引号包裹,用构造器表达式将返回结果封装为Car实体 @Query("SELECT DISTINCT new com.yourpackage.Car(c.carNumber, c.carName) FROM Car c WHERE c.carNumber IS NOT NULL ORDER BY c.carNumber") List<Car> findAllDistinctCars();
如果不需要返回完整Car实体,也可以直接用Object数组接收结果:
@Query("SELECT DISTINCT c.carNumber, c.carName FROM Car c WHERE c.carNumber IS NOT NULL ORDER BY c.carNumber") List<Object[]> findAllDistinctCars();
如果要使用原生SQL,补充nativeQuery = true参数即可:
@Query(value = "SELECT DISTINCT CAR_NUMBER, CAR_NAME FROM CAR WHERE CAR_NUMBER IS NOT NULL ORDER BY CAR_NUMBER", nativeQuery = true) List<Object[]> findAllDistinctCars();
方案2:方法名查询实现
如果仅需用方法名规则实现,注意By后仅写过滤条件,该方式会对返回的整个Car实体所有字段去重,仅适合Car实体只有carNumber、carName两个字段的场景:
// By后仅保留过滤条件,Distinct作用于返回结果去重 List<Car> findDistinctByCarNumberIsNotNull(Sort sort);
调用方式保持不变:
myRepo.findDistinctByCarNumberIsNotNull(Sort.by("carNumber"));
内容的提问来源于stack exchange,提问作者pixel
相关产品推荐
相关产品推荐

