JPA 2.0 CriteriaBuilder帮助 - 如何选择与某个查询匹配的最大(最大)值?

时间:2012-09-24 15:37:22

标签: java hibernate jpa ejb criteria-api

对于这个相当基本的问题感到抱歉,但我必须快速完成某种原型工作,这是我第一次涉足JPA。

我有一个类,System有一个Snapshot项列表,每个都有一个数字ID和一个SystemID。

如何查询快照,例如:

select top 1 ID from Snapshots
where Snapshots.SystemID = X 
order by Snapshots.ID desc; 

我知道如何把where查询放进去,不知道把我的“最大”位放在哪里。

谢谢!

public Snapshot GetMostRecentSnapshotByID(int systemID) {

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<mynamespace.Snapshot> criteria = 
            cb.createQuery(mynamespace.Snapshot.class);
    Root<mynamespace> snapshot = criteria.from(mynamespace.Snapshot.class);
    criteria.where(cb.equal(snapshot.get(Snapshot_.systemID), systemID));

    //OK -- where does this guy go?
    cb.greatest(snapshot.get(Snapshot_.id));

    return JPAResultHelper.getSingleResultOrNull(em.createQuery(criteria));
}

澄清:我的快照类有以下(片段) @

Entity
public class Snapshot implements Serializable {



    @Id
    @GeneratedValue
    private int id;

    @ManyToOne
    @JoinColumn(name = "systemID", nullable = false)
    private System system;

我可以使用System对象查询数字ID来查找特定系统的快照吗?

对不起,如果那令人困惑!

1 个答案:

答案 0 :(得分:2)

你对使用实体和属性而不是表和列的jpa感到有点困惑;如果您正在学习我建议您首先尝试使用jpql实现您的查询,例如:

String q = "from Snapshot s where s.systemID = :systemID order by s.id desc";
TypedQuery<Snapshot> query = em.createTypedQuery(q, Snapshot.class);
query.setParameter("systemID", systemID);
return query.getFirstResult();
// return a Snapshot object, get the id with the getter

(最好将(@OneToMany)快照映射到系统实体而不是使用原始ID)

那么你可以试试CriteriaBuilder(这里不使用元模型):

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Object> cq = cb.createQuery();
Root<Snapshot> r = cq.from(Snapshot.class);
cq.where(cb.equal(r.get("systemID"), systemID));
cd.orderBy(cb.desc(r.get("id")));
em.createQuery(cq).geFirsttResult();

如果你想制作where...and...(但在这个问题中不是你的情况),那就是:

[...]
Predicate p1 = cb.equal(r.get("systemID"), systemID));
Predicate p2 = cb. /* other predicate */
cb.and(p1,p2);
[...]

编辑:

  

我可以查询数字ID,使用System对象来查找   特定系统的快照?

当然,你可以这样做(假设System有一个名为id的@Id属性):

String q = "from Snapshot s where s.system.id = :systemID order by s.id desc";
[...]

其中s.system.id表示:s(Snapshot)的属性系统(类System)的属性id(整数)。

或者,如果你有System实体,你可以直接比较对象:

String q = "from Snapshot s where s.system = :system order by s.id desc";
query.setParameter("system", system);
[...]

使用CriteriaBuilder(和元模型):

Metamodel m = em.getMetamodel();
Root<Snapshot> snapshot = cq.from(Snapshot.class);
Join<Snapshot, System> system = snapshot.join(Snapshot_.system);
cq.where(cb.equal(System_.id, systemID));
[...]