java 从日期中提取年份的 Hibernate 标准

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10470502/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:11:28  来源:igfitidea点击:

Hibernate Criteria extracting Year from date

javahibernate

提问by user829237

Im creating a hibernate criteria that will check if a contract is/has been valid during a year. The contract has a start and end-date as a standard date-field.

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

So being used to SQL-SERVER, i would think something in the lines of this SQL:

所以习惯了 SQL-SERVER,我会想到这个 SQL 中的一些东西:

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

The questionmark is the given year as an integer.

问号是给定年份的整数。

So how to transform this to a hibernate criteria?

那么如何将其转换为休眠标准呢?

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));

As you can see, i am missing the bit where i convert the date's to a year so it can be compared. Naturally my code does not run as it is.

如您所见,我遗漏了将日期转换为年份的部分,以便进行比较。当然,我的代码不会按原样运行。

Any suggestion on how to get the desired results?

关于如何获得所需结果的任何建议?

回答by Pau Kiat Wee

It seem like the API does not directly support what you wanted, but there is workaround that you might consider.

API 似乎并不直接支持您想要的,但您可能会考虑一些解决方法。

Solution 1:

解决方案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();
}

Example output of the two methods:

两种方法的输出示例:

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

Solution 2:

解决方案2:

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

回答by Vipul

Use Restrictions.sqlRestrictionthat will solve your problem

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

回答by Tim Van Laer

If you use JPA criteriaBuilder, you can use the criteriaBuilder.functionmethod. E.g.

如果您使用 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);
   }
});

(I use Spring Data Specificationsin this example to query the database. contractRepositoryis thus of type JpaSpecificationExecutor)

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