gpt4 book ai didi

java - 使用条件查询选择 OneToMany 关系的最后一个(或第一个)插入元素?

转载 作者:太空宇宙 更新时间:2023-11-04 07:11:51 25 4
gpt4 key购买 nike

考虑实体A与实体B具有单向@OneToMany关系。 B 在持久化时设置了一个持久时间戳字段,此后从未更改。

如何进行条件(元组)查询,为每个 A 返回添加到集合中的最后一个(或第一个)B

到目前为止,这是我的看法:

// Root query
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<A> root = q.from(A.class);
Join<A, B> bItem = root.join("listOfB");

// Subquery
Subquery<Date> sq = q.subquery(Date.class);
Join<A, B> sqBItem = sq.correlate(bItem);
Expression<Date> sqBItemCreatedOn = sqBItem.get("createdOn"); // <-- TS on sqBItem
sq.select(cb.greatest(sqBItemCreatedOn)).groupBy(root);

// Back to the root query
Expression<Date> bItemCreatedOn = bItem.get("createdOn"); // <-- TS on bItem
q.multiselect(root, bItem).where(cb.equal(bItemCreatedOn, sq));

em.createQuery(q).getResultList(); // <-- fails

我也尝试过

q.multiselect(root, cntItem).where(cb.in(cntCreatedOn).value(sq));

但没有效果。

请注意,此阶段的关系是单向,因此我想知道子查询部分是否正常工作。通过建立双向关系,我想我可以查询 B 并在 A 上进行分组,但我无法控制域模型。

最佳答案

这是我的尝试(没有子查询):

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<A> root = q.from(A.class);
Join<A, B> bItem = root.join("listOfB");
q.multiselect(
root.alias("A"),
cb.greatest(bItem.<Date>get("createdOn")).alias("TS")); //MAX
// cb.least(bItem.<Date>get("createdOn")).alias("TS")); //MIN
q.orderBy(cb.asc(root));
q.groupBy(root);

List<Tuple> tuples = em.createQuery(q).getResultList()
for (Tuple array : result) {
System.out.println(array.get("A").toString() + ":\t" + array.get("TS"));
}

从 JPQL 的角度来看,这可能看起来像:

SELECT root, MAX(b.createdOn)
FROM A root JOIN root.listOfB bItem
GROUP BY root
ORDER BY root;

关于java - 使用条件查询选择 OneToMany 关系的最后一个(或第一个)插入元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20538522/

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