2013-01-18 62 views
2

我試着去學習和了解JPA標準。 到目前爲止,我在SQL中非常有能力,並且在Hibernate Criteria和HQL中相當有能力。JPA標準析取

我試圖做一個非常簡單的選擇與OR語句。

在普通的SQL我選擇這個樣子的:

SELECT * FROM CHANGED_LOG 
WHERE key1 = 52540 AND objectCode = 'Order' 
OR key1 = 48398 AND objectCode = 'Package' 

這給了我所有行上鍵1 = 52540和目標代碼等於訂單 也是所有行上鍵= 48398和目標代碼等於包。 這正是我想要的。

所以試圖用JPA標準,要做到這一點(這似乎格外複雜...),我最好的猜測,到目前爲止一直是這個:

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 

    CriteriaQuery<ChangedLogBean> query = builder.createQuery(ChangedLogBean.class); 
    Root<ChangedLogBean> from = query.from(ChangedLogBean.class); 
    CriteriaQuery<ChangedLogBean> select = query.select(from); 

    Predicate orderChangedLogBeans = builder.conjunction(); 
    builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 
    builder.and(orderChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.OrderBean)); 

    Predicate packageChangedLogBeans = builder.conjunction(); 
    builder.and(packageChangedLogBeans, builder.equal(from.get("key1"), packageId)); 
    builder.and(packageChangedLogBeans, builder.equal(from.get("objectCode"), ChangedLogBean.ObjectType.PackageBean)); 

    Predicate orderOrPackage = builder.disjunction(); 
    orderOrPackage.getExpressions().add(orderChangedLogBeans); 
    orderOrPackage.getExpressions().add(packageChangedLogBeans); 

    query.where(orderOrPackage); 

    return entityManager.createQuery(select).getResultList(); 

哇。很多簡單查詢的行...但仍然,這從數據庫返回給我每一行。

我在這裏做錯了什麼?

感謝您的所有有用的答案:)

回答

4

在這種情況下,首先要做的是爲了記錄生成的查詢配置JPA提供商。一個例子見this q/a

要回答你的問題,我不確定使用getExpressions(),所以我建議以下粗魯的做法:

Predicate p1 = builder.equal(...); 
Predicate p2 = builder.equal(...); 
Predicate p3 = builder.equal(...); 
Predicate p4 = builder.equal(...); 

Predicate p5 = builder.and(p1, p2); 
Predicate p6 = builder.and(p3, p4); 

query.where(builder.or(p5, p6)); 

你的錯誤是這樣的一行:

builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 

將不會修改orderChangedLogBeans。你必須得到由CriteriaBuilder#and()而是返回的謂詞:

orderChangedLogBeans = builder.and(orderChangedLogBeans, builder.equal(from.get("key1"), orderId)); 
+0

感謝。簡化和美麗。奇蹟般有效。 – user829237