2012-03-29 13 views
6

Herkes, aşağıda belirtilen JPA sorgusu için JPA ölçütü sorgusunu almama yardımcı olabilir.JPA Kriteri sorgusu kullanarak bu sorgu nasıl yazılır?

Criteria criteria = entityManager.createCriteria(Person.class); 
Criteria languageCriteria = criteria.createCriteria("language"); 

languageCriteria.add(Restrictions.like("locale", locale)); 

criteria.add(Restrictions.like("name", name)); 
criteria.add(Restrictions.between("time", startDate, endDate)); 

criteria.addOrder(Order.asc("name")); 

ve JPA 2.0 benim ilk deneme: Kişi burada Dil de ilişkili olduğu varsayılırsa

SELECT p,l FROM Person p 
LEFT JOIN Language l ON (p.language = l.language and l.locale like :locale) 
AND p.name like :name 
AND p.time BETWEEN :startDate 
AND :endDate order by name asc 
+0

Kişilerinizi ve Dilinizi uygulamalarınızı gösterebilir misiniz? –

cevap

10

Eski Hibernate böyle yapardı

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Person> criteria = builder.createCriteria(Person.class); 
Root<Person> pRoot = criteria.from(Person.class); 
Join<Person, Language> langJoin = criteria.join("language", JoinType.LEFT); 

Predicate conjunction = builder.conjunction(); 

criteria.where(builder.and(
    builder.like(langJoin.get(Language_.locale), locale), 
    builder.like(pRoot.get(Person_.name), name), 
    builder.between(pRoot.get(Person_.time), startDate, endDate)); 

criteria.orderBy(builder.asc(pRoot.get(Person_.name))); 

lütfen haber verin bu sizin için çalışıyorsa.

Düzeltme: Yalnızca bir tane where numaralı çağrıyı kullanmak için güncelleştirilmiş sorgu.

+4

Kısıtlamalar, JPA spesifikasyonlarının bir parçası değildir, bir Hazırda Bekletme özelliği – perissf

+0

Doğru, JPA 2'ye çevirmem gerekiyor 2 –

+0

Hey, ilk önce teşekkürler, bunu soruya koymuş olmalıyım. Varlıklar ** kişi/dil ilişkisi yoktur. Hem kişi hem de dil, katıldığım ortak bir sütun (dil (varchar)) var. Benim için sorun olan şey, bir ** SOL DIŞI JOIN ** yapmam gerektiğidir, böylece kişi için dil bilgisi mevcut değilse, yine de, dil ile ilgili kişi verilerini null olarak alabilmem gerekir . – user1300877

6

johncarl tarafından verilen cevap kabul edilmesine rağmen, bana doğru görünmüyor. CriteriaQuery.where için JavaDocs() de ki:

belirtilen mantıksal ifadelere göre sorgu sonucunu kısıtlamak için sorguyu değiştirin. Varsa, önceden eklenen kısıtlamalarını değiştirir.

Anladığım kadarıyla, aşağıdaki satırları (vererek kısıtlamalar) daha önce verilen kısıtlamaları geçersiz kılar:

criteria.where(builder.like(langJoin.get(Language_.locale), locale)); 
criteria.where(builder.like(pRoot.get(Person_.name), name)); 
criteria.where(builder.between(pRoot.get(Person_.time), startDate, endDate)); 

Bunun anlamı başlangıç ​​ve bitiş tarihleri ​​arasında sadece son kısıtlama (sonunda) kalırdı.

Ben johncarl cevabı değişiklikler aşağıdaki önermek threfore:

CriteriaBuilder builder = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Person> criteria = builder.createCriteria(Person.class); 
Root<Person> pRoot = criteria.from(Person.class); 
Join<Person, Language> langJoin = criteria.join("language", JoinType.LEFT); 

Predicate[] restrictions = new Predicate[] { 
    builder.like(langJoin.get(Language_.locale), locale), 
    builder.like(pRoot.get(Person_.name), name), 
    builder.between(pRoot.get(Person_.time), startDate, endDate) 
}; 

criteria.where(builder.and(restrictions)); 

criteria.orderBy(builder.asc(pRoot.get(Person_.name))); 

Ancak bu kod gerçekten çirkin görünüyor! Lütfen, yanlış olup olmadığını düzenlemek için çekinmeyin ve daha iyi bir çözüm görürseniz yorum yapın! Zevkli olurdum!

+0

Gerçekten sizin ipucunuz için teşekkür ederim. ölçüt.bölüm (...) aşamalı olarak kullanılamaz, çünkü potansiyel olarak tamamen geçmiş olan kriterlerin yerini alır. diğer tarafta, builder.and'ın ("nerede olduğu tahmin dizisi") tek bir sorunu vardır. Harika bir çözüm, pho312 :) – Hartmut

+0

Harika bir ipucu için teşekkür ederiz! Yaklaşımını çok beğendim. Ben sadece bir ArrayList yapabilir ve sadece geldikleri gibi kriterler ekleyebilir ekleyebilirsiniz. Öte yandan, neden bilmiyorum ama pRoot.get (Person_.name) benim için çalışmıyor. Anume Person_ sözdizimi ile bir hata alıyorum. – moldovean

İlgili konular