2017-01-16 13 views
1

我有一個查詢,我會寫在較舊的Hibernate中(利用SessionFactory bean)。但是,我已經轉向Spring Boot,現在正在使用JPA 2,它本質上像是一個Hibernate的抽象層。任何人都可以指導我如何添加限制?我相信我現在必須在JPA中使用EntityManager bean。這是舊的查詢。用EntityManger使用JPA2重寫Hibernate SessionFactory查詢,涉及日期限制

@Override 
@SuppressWarnings("unchecked") 
public List<Party> queryPartiesBetweenDates(Date startDate, Date endDate, String sortBy, Integer count) { 
    Criteria criteria = getCurrentSession().createCriteria(Party.class); 
    if (startDate != null) { 
     criteria.add(Restrictions.ge("startDate", startDate)); 
    } 
    if (endDate != null) { 
     criteria.add(Restrictions.lt("endDate", endDate)); 
    } 
    if (count != null) { 
     criteria.setMaxResults(count); 
    } 
    if (sortBy == null || !sortBy.equals("distance")) { 
     criteria.addOrder(Order.asc("startDate")); 
    } 
    return criteria.list(); 
} 

謝謝!

+1

這將有所幫助。 https://www.jumpingbean.co.za/blogs/jpa2-criteria-api – Jobin

回答

1

CriteriaBuilder比本地hibernate Restriction API要冗長得多,主要原因是當你使用MetaModel時它是完全鍵入的,這意味着如果列的類型或名稱導致代碼不能編譯一個查詢無效。 下面是一個不使用生成的MetaModel類的例子,大部分類似於舊的Hibernate代碼。

EntityManager em = emf.createEntityManager(); // or injected 

CriteriaBuilder cb = em.getCriteriaBuilder(); 
CriteriaQuery<Party> query = cb.createQuery(Party.class); 
Root<Party> partyRoot = query.from(Party.class); 
query.select(partyRoot); 

Predicate predicate = null; 
Path<Date> startDatePath = partyRoot.<Date>get("startDate"); 
if (startDate != null) { 
    predicate = cb.greaterThanOrEqualTo(startDatePath, startDate); 
} 
if (endDate != null) { 
    Predicate additionalPredicate = cb.lessThanOrEqualTo(partyRoot.<Date>get("endDate"), startDate); 
    if (predicate == null) { 
     predicate = additionalPredicate; 
    } else { 
     predicate = cb.and(predicate, additionalPredicate); 
    } 
} 
query.where(predicate); 

if (sortBy == null || !sortBy.equals("distance")) { 
    query.orderBy(cb.asc(startDatePath)); 
} 

return em.createQuery(query).setMaxResults(count).getResultList(); 

如果你有很多謂詞,它可能是一個好主意,將它們添加到列表或處理他們創造一個實用方法。

+0

非常感謝你! – tsaebeht

+0

我喜歡你如何繞過metamodal類的使用。大多數情況下,每個查詢都可以在沒有metamodal類的情況下編寫嗎? – tsaebeht

+1

只要知道字段名稱,就不需要靜態元模型。有時你必須從Root.get()中返回返回值,因爲''''Path'''和''Expression'''是非常通用的,你可能需要知道該字段引用了一個collection元素您可以將其用於連接語法。然而,最好的選擇是生成(靜態)元模型作爲你構建的一部分(Annotation處理),這將生成一個名爲'''Party_'''的類,所以你可以使用''''Party_.startDate'''來獲得路徑,然後它是完全類型安全的。 –