java - 比较jpa中的时间戳列而不丢失微秒

标签 java sql oracle hibernate jpa

我有一个 java.lang.String,其中包含微秒精度的时间戳。 我想通过 JPA

将此时间戳与 Oracle 数据库后端中的 TIMESTAMP 列进行比较

(在 query.setParameter 方法参数中)

查询:

select CUSTOMER_NAME from CUSTOMER where REG_TIME < timestamp_which_i_want_to_pass;

当我在 stackoverflow_link 给出的答案中提到时我知道要与数据库时间戳进行比较的 javatype 应该是 java.util.Date 或 java.util.Calendar。

我的问题是,如果我将时间戳(字符串形式)转换为日期/日历,我将丢失微秒。但我需要准确的比较。

如何在不损失微秒的情况下实现这种比较?

最佳答案

java.util.Date 和 java.util.Calendar 都没有微秒精度,所以忘记将它们用作参数!

使用java.sql.Timestamp,它具有纳秒精度。在这种情况下,请小心设置时间戳上的纳米字段 (java.sql.Timestamp way of storing NanoSeconds)

我创建了一个简单的测试场景:

CREATE TABLE precisetimes(id NUMBER(2), precisetime TIMESTAMP(6));
insert into precisetimes values(1, TO_TIMESTAMP('2017-05-31 12:12:12.123456','YYYY-MM-DD HH:MI:SS.FF'));
insert into precisetimes values(2, TO_TIMESTAMP('2017-05-31 12:12:12.12','YYYY-MM-DD HH:MI:SS.FF'));
insert into precisetimes values(3, TO_TIMESTAMP('2017-05-31 12:12:12.123457','YYYY-MM-DD HH:MI:SS.FF'));
commit;

select id,TO_CHAR(precisetime, 'YYYY-MM-DD HH:MI:SS.FF') ptime from precisetimes;

选择全部:

        ID PTIME                       
---------- -----------------------------
         1 2017-05-31 12:12:12.123456   
         2 2017-05-31 12:12:12.120000   
         3 2017-05-31 12:12:12.123457   

准备好以下代码后:

TypedQuery<Precisetimes> q = entityManager.createQuery(
        "select p from Precisetimes p where p.precisetime < :param", 
        Precisetimes.class);
Timestamp ts;
ts = Timestamp.valueOf("2017-05-31 12:12:12.123456");
q.setParameter("param", ts, TemporalType.TIMESTAMP);
System.out.println("result: " + q.getResultList());
ts = Timestamp.valueOf("2017-05-31 12:12:12.123457");
q.setParameter("param", ts, TemporalType.TIMESTAMP);
System.out.println("result: " + q.getResultList());
ts = Timestamp.valueOf("2017-05-31 12:12:12.123458");
q.setParameter("param", ts, TemporalType.TIMESTAMP);
System.out.println("result: " + q.getResultList());

有这样的结果:

result: [id: 2, precisetime: 2017-05-31 12:12:12.12]
result: [id: 1, precisetime: 2017-05-31 12:12:12.123456, id: 2, precisetime: 2017-05-31 12:12:12.12]
result: [id: 1, precisetime: 2017-05-31 12:12:12.123456, id: 2, precisetime: 2017-05-31 12:12:12.12, id: 3, precisetime: 2017-05-31 12:12:12.123457]

我想这就是您所需要的?我在这里上传了测试示例:http://peter.risko.hu/java_incubator/jpa_hibernate_oracle_precisetimestamp.zip

请注意,还有另一种方法,即通过 TO_CHAR 函数将 Oracle 时间戳转换为 Select 语句中的字符串:

select id,TO_CHAR(precisetime, 'YYYY-MM-DD HH:MI:SS.FF') ptime from precisetimes 
  where TO_CHAR(precisetime, 'YYYY-MM-DD HH:MI:SS.FF') > '2017-05-31 12:12:12.123457';

结果:

        ID PTIME                       
---------- -----------------------------
         1 2017-05-31 12:12:12.123456   
         2 2017-05-31 12:12:12.120000   

但是为此,您必须使用 JPA 的 Criteria api 或 native 查询,因为 JPQL 不支持 native 函数。在这种情况下,还要注意在 DB 端和 Java 端使用相同的格式。

关于java - 比较jpa中的时间戳列而不丢失微秒,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44269348/

相关文章:

java - 如何解决这些不兼容的类型?

sql - 在 SQL 中构建基于月份的数据

mysql - 不存在查询

sql - Oracle SQL 查询按组获取剩余金额

oracle - 除默认用户外的所有用户列表

c# - ORA-01000 : maximum open cursors exceeded using oracle instant client and C#

Java - JOptionPane 密码自动保存

java - 将 PFX 静默安装到 Android 系统受信任的 CA 用户 keystore 中

java - 在 Java 中使用嵌套类实现 Iterable

sql - XML 模式中的任何元素都会阻止 XQuery