2012-05-06 20 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类型的因而)