Java 如何将日期参数分配给当前时区的 Hibernate 查询?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/291620/
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
How to assign Date parameters to Hibernate query for current timezone?
提问by serg
When you assign a date to a named SQL parameter Hibernate automatically converts it to GMT time. How do you make it use the current server timezone for all dates?
当您为命名的 SQL 参数分配日期时,Hibernate 会自动将其转换为 GMT 时间。你如何让它在所有日期都使用当前服务器时区?
Lets say you have a query:
假设您有一个查询:
Query q = session.createQuery("from Table where date_field < :now");
q.setDate("now", new java.util.Date());
"now" will be set to GMT time, while "new Date()" gets your current server time.
“now”将设置为 GMT 时间,而“new Date()”将获取您当前的服务器时间。
Thanks.
谢谢。
采纳答案by serg
As it turned out Hibernate doesn't convert dates to GMT automatically, it just cuts off time if you use query.setDate()
, so if you pass "2009-01-16 12:13:14" it becomes "2009-01-16 00:00:00".
事实证明,Hibernate 不会自动将日期转换为 GMT,如果您使用它,它只会截断时间query.setDate()
,所以如果您通过“2009-01-16 12:13:14”,它会变成“2009-01-16 00:00” :00”。
To take time into consideration you need to use query.setTimestamp("date", dateObj)
instead.
考虑到时间,您需要改为使用query.setTimestamp("date", dateObj)
。
回答by Clay
Hibernate is ignorant of timezones. Any timezone conversion should be done prior to executing the query.
Hibernate 不知道时区。任何时区转换都应该在执行查询之前完成。
E.g., if your database server is set to CST, but the user is on EST, you'll need to add 1 hour to any timestamps which are the input to a query.
例如,如果您的数据库服务器设置为 CST,但用户使用 EST,则您需要向作为查询输入的任何时间戳添加 1 小时。
回答by Brian Deterling
We use a custom Hibernate date type. Any time we set a parameter on a query we use a base class or utility method so we can pass the user's timezone into the custom type parameter.
我们使用自定义的 Hibernate 日期类型。每当我们在查询上设置参数时,我们都会使用基类或实用程序方法,以便我们可以将用户的时区传递到自定义类型参数中。
You could get by with just manually adjusting the time in the utility method for queries, but this way dates that are read in or written to the database are also correctly converted. This method also handles the situation where the database stores the date in its local time zone. So even if you have a user in one time zone, a database server in another, and Java using GMT, it can get everything straight. It ends up looking like:
您可以通过手动调整查询的实用程序方法中的时间来解决问题,但这种方式也可以正确转换读入或写入数据库的日期。此方法还处理数据库将日期存储在其本地时区的情况。因此,即使您在一个时区有一个用户,在另一个时区有一个数据库服务器,并且 Java 使用 GMT,它也可以让一切变得简单。它最终看起来像:
Properties properties = new Properties();
properties.setProperty("timeZone", databaseTimeZone);
query.setParameter("from", dateEnteredByUser, Hibernate.custom(LocalizedDateType.class, properties));
As an added bonus, we use this to deal with the fact that SQL Server converts 23:59:59.999 to the next day. In the custom type we check for that and back it off.
作为一个额外的好处,我们使用它来处理 SQL Server 将 23:59:59.999 转换为第二天的事实。在自定义类型中,我们检查并取消它。
回答by Maksim
If you need a timeZonesynchronized value you can use now()in your HQL. Also I suggest you to use the Joda library. It has a hibernate-plugin module.
如果您需要timeZone同步值,您可以在 HQL 中使用now()。另外我建议你使用 Joda 库。它有一个休眠插件模块。
回答by Kayvan Tehrani
Hibernate team has deprecated setTimestamp(String name, Date val)method as well as org.hibernate.Queryinterface since version 5.2:
自5.2版以来,Hibernate 团队已弃用setTimestamp(String name, Date val)方法以及org.hibernate.Query接口:
/* @deprecated (since 5.2) use {@link #setParameter(int, Object)} or
{@link #setParameter(int, Object, Type)} instead
*/
So you can use below code:
所以你可以使用下面的代码:
import org.hibernate.query.Query;
...
Query query = session.createQuery("from Table where date_field < :now");
query.setParameter("now", new Date(), TimestampType.INSTANCE );
It's notable that setDatemethod which cuts down time portion is also deprecated and can be replaced with this option(from the same interface org.hibernate.query.Query):
值得注意的是,减少时间部分的setDate方法也已弃用,可以用此选项替换(来自同一接口 org.hibernate.query.Query):
query.setParameter("firstMomentOfToday", new Date(), DateType.INSTANCE);
If you are going to use it with java 8 and the relevent jdbc drivers like Oracle 'ojdbc8.jar' and supported hibernate versions this might not work as expected, so it's wise to use new java.time.LocalDate and LocalDateTime instead.
如果您打算将它与 java 8 和相关的 jdbc 驱动程序(如 Oracle ' ojdbc8.jar')和支持的休眠版本一起使用,这可能无法按预期工作,因此最好使用新的 java.time.LocalDate 和 LocalDateTime 代替。