任何人都可以幫助我獲得下面提到的JPA查詢的JPA標準查詢。如何使用JPA Criteria查詢編寫此查詢?
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
任何人都可以幫助我獲得下面提到的JPA查詢的JPA標準查詢。如何使用JPA Criteria查詢編寫此查詢?
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
假設人有關係的語言這裏就是你會在較老的Hibernate做什麼:
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"));
和我第一次嘗試在JPA 2.0:
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)));
請讓我知道如果這對你有用。
編輯:更新後的查詢僅使用一個where
調用。
限制不是JPA規範的一部分,它是休眠功能 – perissf 2012-03-29 14:58:56
您是對的,我需要翻譯爲JPA 2 – 2012-03-29 15:10:13
嘿,首先感謝,我應該把它放在這個問題上。 有沒有**關係** b/w實體的人和語言。人員和語言都有一個共同的列(語言(varchar)),我將加入該列。對我造成的問題是,我需要做一個** LEFT OUTER JOIN **,這樣如果沒有可用於該人的語言數據,我仍然應該能夠將語言對象的人員數據作爲空值。 – user1300877 2012-03-29 18:21:08
儘管johncarl給出的答案已被接受,但它對我來說並不正確。對於CriteriaQuery.where()的Javadoc說:
修改查詢根據 指定布爾表達式來限制查詢結果。替換之前添加的 限制(若有)。
據我瞭解,以下各行(給予限制)將覆蓋前面給出的限制:
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));
這意味着,在年底開始和結束日期之間只有最後一個限制( )將保持。
我threfore提出以下修改johncarl的回答是:
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)));
但是,此代碼看起來真難看!請隨時編輯,如果它是錯誤的,並評論它,如果你看到更好的解決方案!我會很優雅!
你可以顯示你的人員和語言的實現嗎? – 2012-03-29 14:20:43