13

我正在创建一个休眠标准,用于检查合同在一年内是否/已经有效。合同具有作为标准日期字段的开始日期和结束日期。

所以习惯了 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));

如您所见,我缺少将日期转换为年份以便进行比较的位。自然,我的代码不会按原样运行。

关于如何获得预期结果的任何建议?

4

3 回答 3

14

看起来 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));
于 2012-05-06T13:04:45.273 回答
5

使用Restrictions.sqlRestriction它将解决您的问题

于 2012-05-06T12:53:55.587 回答
5

如果您使用 JPA 标准构建器,则可以使用该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);
   }
});

(我在这个例子中使用 Spring Data SpecificationscontractRepository来查询数据库。因此是 type JpaSpecificationExecutor

于 2015-10-27T12:42:02.913 回答