2012-05-06 22 views
12

我創建休眠條件,將檢查合同是否在一年內有效。合同的開始日期和結束日期是標準日期字段。休眠標準提取年份從日期

所以被用於SQL-SERVER,我會想的東西在這個SQL的線路:

SELECT * FROM CONTRACT WHERE YEAR(startDate) <= ? AND YEAR(endDate) >= ? 

的問號是給定的年份爲整數。

那麼如何將其轉換爲休眠標準呢?

int year = 2011; //Just a testyear for example purposes. 
DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", year)) 
    .add(Restrictions.ge("endDate", year)); 

正如您所看到的,我錯過了將日期轉換爲一年的位,因此可以進行比較。自然,我的代碼不會按原樣運行。

有關如何獲得預期結果的任何建議?

回答

13

它看起來像API不直接支持你想要的東西,但你可能會考慮解決方法。

解決方案1:兩種方法的

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.le("startDate", toEndOfYear(year)) 
    .add(Restrictions.ge("endDate", toStartOfYear(year))); 

public Date toStartOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND, 0); 
    return calendar.getTime(); 
} 

public Date toEndOfYear(int year) { 
    Calendar calendar = Calendar.getInstance(); 
    calendar.set(Calendar.YEAR, year); 
    calendar.set(Calendar.DAY_OF_YEAR, 0); 
    calendar.set(Calendar.HOUR_OF_DAY, 0); 
    calendar.set(Calendar.MINUTE, 0); 
    calendar.set(Calendar.SECOND,-1); 
    return calendar.getTime(); 
} 

輸出示例:

System.out.println(toStartOfYear(2013)); 
System.out.println(toEndOfYear(2013)); 

Mon Dec 31 00:00:00 MYT 2012 
Sun Dec 30 23:59:59 MYT 2012 

解決方案2:

DetachedCriteria criteria = DetachedCriteria.forClass(Contract.class) 
    .add(Restrictions.sqlRestriction("YEAR(startDate) >= ? ", year,Hibernate.INTEGER)) 
    .add(Restrictions.sqlRestriction("YEAR(endDate) <= ? ", year,Hibernate.INTEGER)); 
+1

解決方案1是一個很好的清潔的替代,儘管'toEndOfYear'方法應加1後,年,因爲它傳入'cal.set',否則你會得到前一年的結束 – Numeron

5

使用Restrictions.sqlRestriction,將解決你的問題

3

如果使用JPA criteriaBuilder,可以使用criteriaBuilder.function方法。例如。

contractRepository.findAll(new Specification<Contract>() { 
    @Override 
    public Predicate toPredicate(Root<Contract> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 
    return cb.ge(cb.function("year", Integer.class, root.get(Contract_.endDate)), year); 
    } 
}); 

(I使用Spring數據Specifications在這個例子中,以查詢數據庫。contractRepositoryJpaSpecificationExecutor類型的因而)