我有一个 java.lang.String,其中包含微秒精度的时间戳。
我想通过 JPA
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/