![](/img/trans.png)
[英]Is it possible to add count(*) and groupBy to Spring Data Jpa Specification?
[英]Spring Data JPA Specification groupBy
首先對不起我的英語。
我想使用 jpa 進行分組,例如:從數據流組中按腳本、dstip 選擇腳本、灰塵、計數(*)。 所以,寫這些代碼:
public class DataflowSpec {
public static Specification<Dataflow> search(final String[] group, final String[] sort, final String[] desc) {
return new Specification<Dataflow>() {
@Override
public Predicate toPredicate(Root<Dataflow> root1, CriteriaQuery<?> query1, CriteriaBuilder builder) {
// TODO Auto-generated method stub
CriteriaQuery<Tuple> query = builder.createQuery(Tuple.class);
Root<Dataflow> root = query.from(Dataflow.class);
query.multiselect(root.get("srcip"), root.get("dstip"), builder.count(root));
query.groupBy(root.get("srcip"), root.get("dstip"));
query.orderBy(builder.desc(root.get("srcip").as(BigInteger.class)));
return query.getRestriction();
}
};
}
}
但是,SQL日志是:休眠:
select
count(dataflow0_.id) as col_0_0_
from
Dataflow dataflow0_
休眠:
select
dataflow0_.id as id1_2_,
dataflow0_.byteall as byteall2_2_,
dataflow0_.bytedn as bytedn3_2_,
dataflow0_.byteup as byteup4_2_,
dataflow0_.dstip as dstip5_2_,
dataflow0_.dstport as dstport6_2_,
dataflow0_.engieid as engieid7_2_,
dataflow0_.flag as flag8_2_,
dataflow0_.netid as netid9_2_,
dataflow0_.pkgall as pkgall10_2_,
dataflow0_.pkgdn as pkgdn11_2_,
dataflow0_.pkgup as pkgup12_2_,
dataflow0_.protocolid as protoco17_2_,
dataflow0_.rtt as rtt13_2_,
dataflow0_.srcip as srcip14_2_,
dataflow0_.srcport as srcport15_2_,
dataflow0_.updatetime as updatet16_2_
from
Dataflow dataflow0_ limit ?
那么,如何解決呢? 謝謝!
您可以通過specification
實現spring數據group by
,只需按照
對於 2.0 之前或之后的版本,請參閱第 2.6 節或第 3.6 節。 對於單個存儲庫操作,兩個版本具有相同的解決方案。 對於 *all * 存儲庫解決方案,在 2.0 之前使用定制的工廠 bean ,而在 2.0 之后,此工廠 bean 操作被省略。
public Map<AlarmMsg.AlarmLevel, Long> testSpecification(String neId) {
SingularAttribute attribute = AlarmData_.isClear;
Specification<Object> where = Specification.where(
(root, query, cb) -> cb.equal(root.get(attribute), false)
);
final Map<AlarmMsg.AlarmLevel, Long> result = alarmDataRepository.groupAndCount(AlarmData_.alarmLevel, where );
return result;
}
存儲庫:
public interface AlarmDataRepository extends JpaRepository<AlarmData, Long>, JpaSpecificationExecutor<AlarmData>, CustomizedGroupCountRepository {
片段存儲庫及其實現:
public interface CustomizedGroupCountRepository {
Map<AlarmMsg.AlarmLevel, Long> groupAndCount(SingularAttribute singularAttribute, Specification where);
}
public class CustomizedGroupCountRepositoryImpl implements CustomizedGroupCountRepository {
private final EntityManager entityManager;
public CustomizedGroupCountRepositoryImpl(EntityManager entityManager) {
Assert.notNull(entityManager, "EntityManager must not be null!");
this.entityManager = entityManager;
}
@Override
public Map<AlarmMsg.AlarmLevel, Long> groupAndCount(SingularAttribute singularAttribute, Specification where) {
final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Tuple> query = criteriaBuilder.createQuery(Tuple.class);
final Root<AlarmData> root = query.from(AlarmData.class);
final Path<AlarmMsg.AlarmLevel> expression = root.get(singularAttribute);
query.multiselect(expression, criteriaBuilder.count(root));
query.select(criteriaBuilder.tuple(expression, criteriaBuilder.count(root)));
query.where(where.toPredicate(root, query, criteriaBuilder));
query.groupBy(expression);
final List<Tuple> resultList = entityManager.createQuery(query).getResultList();
return resultList.stream()
.collect(toMap(
t -> t.get(0, AlarmMsg.AlarmLevel.class),
t -> t.get(1, Long.class))
);
}
}
one-for-all-repository 和 one-for-single-repository 的主要區別在於,在 one-for-single-repository 的情況下,它可以訪問真實的實體類,如 spring 參考文檔中的User
。 這樣你就不需要使用泛型類型來引用任何類型的實體,而在 one-for-all-repository 的情況下,自定義方法的實現使用泛型類型,它的類信息可以(或必須)是從注入的JpaEntityInformation
獲得,如第 3.6 節所述。
對於仍在尋找如何在 Spring jpa 規范中應用“group by”的人,您可以使用類似以下代碼段的內容:
...
private Dataflow dataflowFilter;
@Override
public Predicate toPredicate(Root<Dataflow> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
Predicate predicate = cb.conjunction();
predicate.getExpressions().add(cb.equal(root.get("id"), dataflowFilter.getId()));
...
cq.groupBy(root.get("id"));
...
return predicate;
}
規范不支持 groupBy。 SimpleJpaRepository 替換 query.select/multiselect 由 query.select(root)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.