我正在使用Spring Boot和Spring Data Jpa编写应用程序。
我有一个使用RSQL(我使用this库)和Specification的方法来对数据库的where子句进行过滤器调用。
我的存储库:
public interface BaseRepository<M extends BaseModel> extends JpaRepository<M,Long>,JpaSpecificationExecutor<M>{
}
在服务中,我调用存储库:
String filter = "createdDate > 2019-09-04T11:52:59.449";
return repository.findAll(toSpecification(filter),pageable).getcontent();
因此,我使用上面的库来生成一个Specification并将其传递到存储库中。
现在,我需要按一些字段对结果进行分组。
问题是如何在规范中添加 count 和 groupBy ?或者,也许我需要创建一个谓词,在其中定义此 count 和 groupBy (以某种方式)并以此为基础进行规范?有什么更好的方法呢?
更新#0
我已经设法在结果sql查询中按组添加了一个组。我创建了一个新的规范对象,在该对象中,我按参数定义了所有分组,然后将此规范与原始规范组合在一起。
String filter = "createdDate > 2019-09-04T11:52:59.449";
Specification<M> groupBySpec = new Specification<M>() {
@Override
public Predicate toPredicate(Root<M> root,CriteriaQuery<?> query,CriteriaBuilder criteriaBuilder) {
List<Expression<?>> groupByParams = new ArrayList<>();
groupByParams.add(root.get("param1"));
groupByParams.add(root.get("param2"));
query.groupBy(groupByParams);
return query.getGroupRestriction();
}
};
return repository.findAll(groupBySpec.and(toSpecification(filter)),pageable).getcontent();
问题是它总是选择所有列,但我只需要按组选择那些列。
结果是我得到一个SQL异常:ERROR: column "columnName" must appear in the GROUP BY clause or be used in an aggregate function
。
我已经尝试过使用criteriaQuery.multiselect(root.get("column1"),root.get("column2")).distinct(true).getGroupRestriction();
这样的多选功能,但是无论如何它都会选择所有列。
如果我使用@Query("query")
(在其中定义要选择的列,但需要使用Criteria Api / Specification来工作),它将起作用。