尝试转换时间戳字段时,oracle.sql.timestamp 无法转换为 java.util.date

oracle.sql.timestamp cannot be cast to java.util.date when trying to convert timestamp field

我的数据库 table 中有 LATEST_MODIFICATION_DATE 字段,它是时间戳数据类型。 我正在使用平面 jdbcTemplate 进行数据库执行查询。

下面是我的部分代码,运行良好。但是我看到在线上有问题

latestModDate = rowSet.getString("LATEST_MODIFICATION_DATE");

因为我试图将 LATEST_MODIFICATION_DATE 时间戳数据类型字段视为字符串,所以它可能会在我的代码中产生问题。

我尝试更新下面的行,然后将 LATEST_MODIFICATION_DATE 声明为 timestamp 数据类型,但出现 oracle.sql.timestamp cannot be cast to java.util.date.

错误
latestModDate = rowSet.getTimestamp("LATEST_MODIFICATION_DATE");

我真的不知道如何将 LATEST_MODIFICATION_DATE 视为时间戳。我真的不想像下面那样在系统 属性 中进行更改,因为我想在代码中处理这个问题:

java -Doracle.jdbc.J2EE13Compliant=true YourApplication
or
System.getProperties().setProperty("oracle.jdbc.J2EE13Compliant", "true")

下面是我的部分代码:

            String orderID = null, extOrdId = null, latestModDate = null;                

            while (rowSet.next()) {
                latestModDate = rowSet.getString("LATEST_MODIFICATION_DATE");
            }

            

您已将 latestModDate 定义为 String,但如您所说,它是数据库中的时间戳,如果您将类型更改为 java.util.Date 之类的类型,然后使用ResultSet.getDate()这个应该解决你的问题:

Date latestModDate = rowSet.getDate("LATEST_MODIFICATION_DATE");

不要使用 java.sql.Datejava.util.Date。使用 java.time.LocalDateTimejava.util.Date 是一个黑客,java.sql.Date 是一个黑客之上的黑客。

LocalDateTime latestModDate;

while (rowSet.next()) {
    latestModDate = rowSet.getObject("LATEST_MODIFICATION_DATE", LocalDateTime.class);
}
  1. 声明 latestModDate 类型 java.sql.Timestamp

  2. latestModDate得到java.time.Instant如下:

    Instant instant = latestModDate.toInstant();
    

获得 Instant 的对象后,您可以根据需要将其转换为任何其他现代日期时间对象,例如

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class Main {
    public static void main(String[] args) {
        Instant instant = Instant.now();
        ZonedDateTime zdt = instant.atZone(ZoneId.of("Europe/London"));
        OffsetDateTime odt = zdt.toOffsetDateTime();
        LocalDateTime ldt = zdt.toLocalDateTime();
        System.out.println(instant);
        System.out.println(zdt);
        System.out.println(odt);
        System.out.println(ldt);
    }
}

输出:

2020-06-27T08:55:12.317754Z
2020-06-27T09:55:12.317754+01:00[Europe/London]
2020-06-27T09:55:12.317754+01:00
2020-06-27T09:55:12.317754

一些补充说明:

  1. 不要使用过时且容易出错的 java.util 日期时间 API。使用 modern date-time API.
  2. LocalDateTime 删除您的业务逻辑中可能需要的区域偏移量和区域 ID 等信息。因此,根据下面显示的 table (Ref) 选择合适的 class:

[更新]

您需要在代码中进行的更改:

java.sql.Timestamp latestModDate;

if (rowSet.next()) {
    latestModDate = ((oracle.sql.TIMESTAMP) rowSet.getObject("LATEST_MODIFICATION_DATE")).timestampValue();
}

// If the record exist, update accordingly, else insert a new one.
if (latestModDate != null) {
    String sqlUpdate = "update " + tableName + " set LATEST_MODIFICATION_DATE = sysdate, SOURCES = '" + fileName + "' where (ORDERID = '" + orderID + "' and EXTORDID = '" + extOrdId + "') or (ORDERID = '" + orderID + "' and EXTORDID is null)";
    jdbcTemplate.update(sqlUpdate);
    //...

注:函数oracle.sql.TIMESTAMP#timestampValuereturns一个值在java.sql.Timestamp.