2012-09-24 24 views
2

對不起,這個相當基本的問題,但我必須得到某種原型的工作很快,這是我第一次進入JPA。JPA 2.0 CriteriaBuilder幫助 - 如何選擇匹配特定位置查詢的最大(最大)值?

我有一個類,系統有一個快照項目列表,每個都有一個數字ID和一個SystemID。

如何查詢快照這樣說:

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

我知道如何把那裏查詢中,不知道從哪裏把我的「最偉大」的位。

謝謝!

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; 

我就可以查詢的數字ID,VS使用系統對象,找到特定系統的快照?

對不起,如果這是令人困惑!

回答

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,VS使用系統對象,找到 特定系統的快照?

當然,你可以那樣做(因爲系統有一個名爲@Id id屬性):屬性的屬性ID(整數):

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

其中s.system.id指s(快照)的系統(類系統)。只是

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)); 
[...] 
+0

我確實也有一對多的映射,I:

或者,如果你有系統的實體,您可以直接比較的對象:

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

使用CriteriaBuilder(和元模型)不知道如何指定該列,如上面 – Yablargo

+0

所示,在這種情況下,您的Snapshot實體應與System(mappedBy)具有反向關係,從而使systemID屬性變爲冗餘;無論如何,請僅僅忽略那條評論 –

+0

是的,我應該包括那個。我有一個Snapshot類,它具有映射回來的System屬性。但是說我有一個對應於系統ID的id(5) - 我想直接查詢,我可以這樣做嗎?我知道底層字段是systemID,並在快照類 – Yablargo