Java、时间相关对象和oracle to_date函数

Java, time-related objects and oracle to_date function

我有一个 Oracle 数据库,其中名为 UPDATED 的列在 sqlDeveloper 中标记为 TIMESTAMP(6)。该列中的示例条目是 05-MAY-18 04.49.45.000000000

我想使用准备好的语句对其执行以下查询:

SELECT * FROM EXAMPLE_TABLE WHERE UPDATED > TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS'.

问题是 - 我如何绑定 Java 日期时间对象(来自 org.joda.time.LocalDateTimejava.time.LocalDateTime 或任何其他同时保留数据和时间的对象?

这是一个测试片段,无论我做什么我都无法让它工作(除了我绑定 new Date(2018, 5,5) 的情况,但首先它只是没有时间的日期,其次 sql.Date已经过时了。

public class Dbaccess {
    public static void main(String[] args) throws SQLException {
        Connection connection = DriverManager.getConnection("someurl", "some_username", "some_password");
        PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM EXAMPLE WHERE UPDATED > TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS')");
        preparedStatement.setObject(1, LocalDateTime.now());
        ResultSet resultSet = preparedStatement.executeQuery();
        System.out.println("resultSet:" + resultSet);
        while(resultSet.next()) {
            System.out.println(resultSet.getString("some_id"));
        }
    }
}

不幸的是,我得到 Exception in thread "main" java.sql.SQLException: Invalid column type

我们这些天应该如何绑定应该代表日期时间的变量?

尝试像这样使用 setDate :

LocalDateTime ldt = LocalDateTime.now();
//Convert LocalDateTime to SQL TimeStamp
java.sql.Timestamp dateTimeSql = java.sql.Timestamp.valueOf(ldt);
//Set this time stamp to the query
preparedStatement.setDate(1, java.sql.Timestamp.valueOf(dateTimeSql));

或者只是:

preparedStatement.setDate(1, 
     java.sql.Timestamp.valueOf(java.sql.Timestamp.valueOf(LocalDateTime.now()))
);

那么你不需要使用 TO_DATE(?, 'YYYY-MM-DD HH24:MI:SS') 你可以只使用 :

SELECT * FROM EXAMPLE WHERE UPDATED > ?

tl;博士

检查您的 JDBC 驱动程序支持 JDBC 的 版本。

在 JDBC 4.2 及更高版本中,您可以执行以下操作:

myPreparedStatement.setObject(
    … ,
    LocalDateTime.now()
)

在 JDBC 4.2 之前,请参阅

JDBC 4.2

JDBC 4.2 开始,您可以直接与数据库交换 java.time 对象。无需再使用 java.sql.Timestamp

LocalDateTime ldt = LocalDateTime.now() ;  // Better to pass explicitly your desired time zone rather than rely implicitly on the JVM’s current default.

使用 setObject 方法传递给您准备好的语句。

myPreparedStatement.setObject( … , ldt ) ;

检索。

LocalDateTime ldt = myResultSet.getObject( … , LocalDateTime.class ) ;

JDBC 4.1 及更早版本

如果你的JDBC driver is not yet updated for JDBC 4.2 or later, see


关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time 类.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

您可以直接与数据库交换 java.time 对象。使用 JDBC driver compliant with JDBC 4.2 或更高版本。不需要字符串,不需要 java.sql.* 类.

在哪里获取java.time类?

  • Java SE 8, Java SE 9, Java SE 10,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time 类.
    • 捆绑实施的更高版本
    • 对于较早的 Android (<26),ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.