gpt4 book ai didi

java - 使用 Hibernate 供应商使用计数 JPA 2.0 包装条件查询

转载 作者:行者123 更新时间:2023-12-02 13:10:05 25 4
gpt4 key购买 nike

有没有办法用计数查询包装 CriteriaQuery?我的想法是创建一个函数,从任何给定的查询创建计数查询。

例如平面sql:

SELECT
item_type,
count(*) AS lol
FROM inventory_movements
WHERE movement_date_time BETWEEN '2017-05-08 12:00:00' AND '2017-05-08 13:00:00'
GROUP BY item_type

我想创建这样的东西(我知道在这个特定的查询中,不同的计数可以解决问题,但我需要一个通用的解决方案,我想将它用于非 jpa 托管返回类型查询中的分页):

SELECT count(*)
FROM (
SELECT
item_type,
count(*) AS rand_
FROM inventory_movements
WHERE movement_date_time BETWEEN '2017-05-08 12:00:00' AND '2017-05-08 13:00:00'
GROUP BY item_type
) AS sub;

CriteriaQuery 不是 Expression 的实例,因此不能在 criteriaBuilder.count() 中使用;

然后我想我可以将其转换为子查询,因为 CriteriaQuery 和 Subquery 都实现相同的接口(interface),但 Subquery 也实现了 Expression。

但这并不像我想象的那样有效。这是我当前的非工作代码:

public <T>TypedQuery<Long> getCountQuery(CriteriaQuery<T> origQuery) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Long> query = cb.createQuery(Long.class);
Subquery<T> subQuery = (Subquery<T>) origQuery;

query.select(cb.count(subQuery));
return entityManager.createQuery(query);
}

我在运行时遇到以下异常:

java.lang.ClassCastException: org.hibernate.query.criteria.internal.CriteriaQueryImpl cannot be cast to javax.persistence.criteria.Subquery

这在 jpa/hibernate 中是否可能?

最佳答案

@PersistenceContext
private EntityManager em;

...
...
public Page<T1> findByParameters(P p) {
CriteriaQuery<T1> criteriaQuery = (CriteriaQuery<T1>) getEm().getCriteriaBuilder().createQuery(typeToken1.getRawType());
Root<T2> root = (Root<T2>) criteriaQuery.from(typeToken2.getRawType());
criteriaQuery = SpecificationBuilder.of().buildCriteriaQuery(p, root, criteriaQuery, criteriaBuilder);

TypedQuery<T1> query = getEm().createQuery(criteriaQuery);
query.setFirstResult(pageRequest.getPageNumber() * pageRequest.getPageSize());
query.setMaxResults(pageRequest.getPageSize());

Integer totoal = getTotal(criteriaQuery, (CriteriaQueryTypeQueryAdapter) query);
PageImpl<T1> page1 = new PageImpl<>(query.getResultList(), pageRequest, totoal);
return page1;
}

private Integer getTotal(CriteriaQuery<T1> criteriaQuery, CriteriaQueryTypeQueryAdapter query) throws NoSuchFieldException, IllegalAccessException {
String jql = getEm().createQuery(criteriaQuery.orderBy()).unwrap(Query.class).getQueryString();
Field f = CriteriaQueryTypeQueryAdapter.class.getDeclaredField("jpqlQuery");
f.setAccessible(true);
QueryImpl jpqlQuery = (QueryImpl) f.get(query);
Map<String, TypedValue> stringTypedValueMap = jpqlQuery.getQueryParameters().getNamedParameters();
String sql = getSql(jql);
sql = String.format("select count(*) from (%1$s) t", sql);
NativeQuery nativeQuery = (NativeQuery) getEm().createNativeQuery(sql);
int index = 1;
for (Iterator<Map.Entry<String, TypedValue>> iterator = stringTypedValueMap.entrySet().iterator(); iterator.hasNext(); ) {
Map.Entry<String, TypedValue> next = iterator.next();
nativeQuery.setParameter(index, next.getValue().getValue());
index++;
}
return (Integer) nativeQuery.getSingleResult();
}

关于java - 使用 Hibernate 供应商使用计数 JPA 2.0 包装条件查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43993238/

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