gpt4 book ai didi

java - 是否可以将 count(*) 和 groupBy 添加到 Spring Data Jpa 规范?

转载 作者:行者123 更新时间:2023-12-02 09:20:44 28 4
gpt4 key购买 nike

我正在使用 Spring Boot 和 Spring Data Jpa 编写一个应用程序。

我有一个方法,它使用 RSQL(我使用 this 库)和规范来使用 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();

因此,我使用上面的库生成规范并将其传递到存储库。

现在我需要按某些字段对结果进行分组。

问题是如何将 countgroupBy 添加到规范中?或者也许我需要创建一个谓词,在其中定义此 countgroupBy (以某种方式)并据此制定规范?有什么更好的方法吗?

更新#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异常:错误:列“columnName”必须出现在GROUP BY子句中或在聚合函数中使用

我尝试像这样使用多重选择criteriaQuery.multiselect(root.get("column1"), root.get("column2")).distinct(true).getGroupRestriction(); 但无论如何它都会选择所有列。

如果我使用 @Query("query") 来定义要选择的列,但我需要它使用 Criteria Api/Specification 来工作,它就可以工作。

最佳答案

您可以创建自己的 GroupBySpecification 类,该类将 groupBy 表达式添加到其他规范:

public class GroupBySpecification implements Specification {
Specification original;
Parameters parameters; // whatever data needed for calculating groupBy expression

public GroupBySpecification(Specification original, Parameters parameters){
this.original = original;
this.parameters = parameters;
}
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {

Expression<?> expression = ...; // whatever logic needed to be used on parameters...
criteriaBuilder.groupBy(expression);
return original.toPredicate(root, query, criteriabuilder);
}

}

然后你可以像这样使用它:

String filter = "createdDate > 2019-09-04T11:52:59.449";
return repository.findAll(new GroupBySpecification(toSpecification(filter),parameters),
pageable).getContent();

如果您需要计数,请调用适当的存储库方法:

repository.count(new GroupBySpecification(toSpecification(filter),parameters));  

关于java - 是否可以将 count(*) 和 groupBy 添加到 Spring Data Jpa 规范?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58711154/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com