【问题标题】:Date query with Hibernate on Timestamp Column in PostgreSQL在 PostgreSQL 的时间戳列上使用 Hibernate 进行日期查询
【发布时间】:2011-02-02 08:45:09
【问题描述】:

一个表有时间戳列。其中的一个示例值可能是 2010-03-30 13:42:42。使用 Hibernate,我正在执行范围查询 Restrictions.between("column-name", fromDate, toDate)。

该列的Hibernate映射如下。

<property name="orderTimestamp"  column="order_timestamp" type="java.util.Date" />

假设我想找出日期为 2010 年 3 月 30 日和 2010 年 3 月 31 日的所有记录。对该字段的范围查询如下。

Date fromDate = new SimpleDateFormat("yyyy-MM-dd").parse("2010-03-30");
Date toDate = new SimpleDateFormat("yyyy-MM-dd").parse("2008-03-31");
Expression.between("orderTimestamp", fromDate, toDate);

这不起作用。

查询被转换为各自的时间戳,如“2010-03-30 00:00:00”和“2010-03-31 00:00:00”。因此,2010 年 3 月 31 日的所有记录都将被忽略。

解决此问题的一个简单方法是将结束日期设为“2010-03-31 23:59:59”。但是,我想知道是否有办法只匹配时间戳列的日期部分。

另外,Expression.between() 是否包含这两个限制?文档对此没有任何启示。

【问题讨论】:

  • 我相信 between 在两个限制上总是排他的。你为什么不只删除 1 毫秒并为它们每个添加 1 毫秒?
  • @jishi 它依赖于数据库(我相信大部分时间都包括在内)。
  • Shashikant 你能解决这个问题吗?

标签: java hibernate postgresql orm date


【解决方案1】:

,我想知道是否有办法只匹配时间戳列的日期部分。

如果您不想要 TIMESTAMP,请使用 DATE(您不应该使用 type="date" 吗?)。

另外,Expression.between() 是否包含这两个限制?

SQL BETWEEN 运算符的行为似乎是database dependent。使用 PosgresQL,BETWEEN 表达式:

x BETWEEN y AND z

在语义上等价于:

y <= x AND x <= z

即包括在内。

【讨论】:

  • type="date" 没有帮助。想试试你早先的注解想法,但不幸的是,我使用的 Hibernate 版本早于 3.3,其中引入了注解。
  • @Shashikant 我发布的答案有点太快了,没有意识到您正在使用 xml 映射(因此进行了更新)。但事实上,Hibernate 注释对此有一个@Temporal 注释(docs.jboss.org/hibernate/stable/annotations/reference/en/…)。 xml 必须有某种等价物... BTW 你可以控制你的物理模型吗?
  • 除了 DB 模式(即 timstamp 列)和 Hibernate 版本,我可以更改其他任何内容。时间注释听起来很有用,但正如我所提到的,我无法迁移到 Hibernate 3.3+。另外,如果我将时间注释添加为日期,在检索行时,它会截断时间戳到日期吗?如果是,那是不可取的。谢谢你的帮助,帕斯卡。修改 +1。
  • @PascalThivent 使用时间注释作为日期跳过 api 请求上的 gson 序列化,因此在客户端获取上一个日期。如果数据库上的 dob 为 '13-11-1987',则将其设为 '12 -11-1987' 作为 rest api 响应。
【解决方案2】:

“2010-03-31 23:59:59”。边界条件有潜在危险:如果系统在 23:59:59 和 00:00:00 之间有交易,你就会错过它。如果您每天有足够多的交易并且时间足够长,那么报告就会中断,您将花费数小时来找出原因。

PostgreSQL between includes the limits 因此将结束日期设置为 2010-04-01 00:00:00 甚至都不安全。确定使用 lt() 和 gt()。

【讨论】:

  • 还是不行,包括 2010-04-01 00:00 AM
  • 使用 lt("endDate", endDate) where endDate = "2010-04-01 00:00" 将包括结束日期为 2010-04-01 00:00 的记录?我认为情况并非如此。
  • 感谢 PostgreSQL 包含“between”的链接。边界条件并不令人担心,因为时间戳仅记录到秒的精度。要使用小于或大于,我需要使用小于(“2010-04-01 00:00:00”)和大于或等于(“2010-03-30 00” :00:00")
【解决方案3】:

也许您可以将 orderTimestamp 转换为 DATE。用于此的 HQL does have support

【讨论】:

    【解决方案4】:

    使用 cast(your_data, date),记住 cast 函数的第二个参数必须更低,否则将不起作用。

    收件人:Samuel\Maycon

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 1970-01-01
      • 2021-07-24
      相关资源
      最近更新 更多