比较jpa中的timestamp列而不会丢失微秒

时间:2017-05-30 18:25:24

标签: java sql oracle hibernate jpa

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

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

(在query.setParameter方法论证中)

查询:

select CUSTOMER_NAME from CUSTOMER where REG_TIME < timestamp_which_i_want_to_pass;

当我在stackoverflow_link中给出的答案中提到时,我理解要与DB时间戳进行比较的javatype应该是java.util.Datejava.util.Calendar

我的问题是,如果我将timeStamp(在字符串中)转换为Date / Calendar,我将失去微秒。但我需要准确比较。

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

3 个答案:

答案 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端使用相同的格式。