我有一个java.lang.String,其中包含一个微秒精度的时间戳。
我想通过TIMESTAMP
JPA
列进行比较
(在query.setParameter
方法论证中)
查询:
select CUSTOMER_NAME from CUSTOMER where REG_TIME < timestamp_which_i_want_to_pass;
当我在stackoverflow_link中给出的答案中提到时,我理解要与DB时间戳进行比较的javatype应该是java.util.Date
或java.util.Calendar
。
我的问题是,如果我将timeStamp(在字符串中)转换为Date
/ Calendar
,我将失去微秒。但我需要准确比较。
如何在不丢失微秒的情况下实现这种比较?
答案 0 :(得分:0)
有几种可能的方法:
1)将包含数据库中微秒的时间戳的值类型更改为long
,然后将TIMESTAMP
转换为long
并添加填充000
的微秒。例如:
long timestampWithoutMicroSeconds = 1496218445;
long timestampWithMicroseconds = timestampWithoutMicroSeconds * 1000;
然后只需使用您的查询选择正确的结果。
2)根据您的数据库,您可以使用contains
之类的运算符。这意味着您必须将搜索参数(TIMESTAMP
)转换为String
并使用如下查询:
WHERE `column` LIKE '%part%'
这意味着您将选择column
包含'part'的所有记录。示例:
|username|time_with_micro |
|+------+|+------------------|
| test | 1496218445123 |
Select * from table where time_with_micro like %1496218445%
它会选择你的价值。
此外,使用此方法,您必须使用%
符号来定义未知部分。在您的任务中,您需要选择时间以搜索参数开头的所有记录,以避免冲突。然后它会完成您正在寻找的所有记录,所有记录的时间更长(&gt;),然后您正在寻找将被选中。
答案 1 :(得分:0)
您可以使用以下步骤转换参数类型:
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS").format( param);
Timestamp time = Timestamp.valueOf(date);
我希望这会有所帮助。
答案 2 :(得分:0)
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函数将Select语句中的Oracle时间戳转换为String:
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或本机查询,因为JPQL不支持本机函数。在这种情况下,还要注意在DB端和Java端使用相同的格式。