问题
如何您使用 JDBC 将 java.time 类型(例如 LocalDate)插入和检索到 SQL 数据库(例如 H2)中吗?使用PreparedStatement::setDate 和ResultSet::getDate 的旧方法适用于遗留的java.sql.Date 类型,但您希望避免使用这些麻烦的旧日期时间类。通过 JDBC 驱动程序发送 java.time 类型的现代方法是什么?
解决方案
通过 JDBC 交换 java.time 对象有两种方法:
遗留的日期时间类,如 java.util.Date、java.util.Calendar 及其相关的 java.sql 对应类,如 java.sql. sql.Date 的问题是出了名的,它是用有缺陷的、被黑客攻击的方法设计的。它们容易出错、麻烦且令人困惑。尽可能避免使用它们,因为它们现在已被 java.time 类取代。
使用 JDBC 4.2 兼容驱动程序
内置的 H2 JDBC 驱动程序(截至2017-03)似乎符合 JDBC 4.2。兼容的驱动程序可以识别 java.time 类型。 JDBC 委员会没有添加 setLocalDate/getLocalDate 方法,而是添加了 setObject/getObject 方法。
要将数据发送到数据库,只需将 java.time 对象传递给PreparedStatement::setObject。驱动程序会检测传递的参数的 Java 类型并将其转换为适当的 SQL 类型。 java.time.LocalDate 转换为 SQL DATE 类型。有关这些映射的列表,请参阅 JDBC Maintenance Release 4.2 PDF 文档的第 22 节。
myPreparedStatement.setObject(1, myLocalDate); // Automatic detection and conversion of data type.
要从数据库检索数据,请调用 ResultSet::getObject。您可以提供一个附加参数来指定您期望接收的数据类型的类,而不是强制转换生成的 Object 对象。通过显式指定所需的类,您可以获得类型安全性,类型安全性由您的 IDE 和编译器检查和验证。
LocalDate localDate = myResultSet.getObject("my_date_column_", LocalDate.class);
代码示例:
这里是将 LocalDate 值插入并选择到 H2 数据库中的应用程序的完整工作示例:
import java.sql.*; import java.time.LocalDate; import java.time.ZoneId; import java.util.UUID; public class App { public static void main ( String[] args ) { App app = new App ( ); app.doIt ( ); } private void doIt ( ) { try { Class.forName ( "org.h2.Driver" ); } catch ( ClassNotFoundException e ) { e.printStackTrace ( ); } try ( Connection conn = DriverManager.getConnection ( "jdbc:h2:mem:trash_me_db_" ) ; Statement stmt = conn.createStatement ( ) ; ) { String tableName = "test_"; String sql = "CREATE TABLE " + tableName + " (\n" + " id_ UUID DEFAULT random_uuid() PRIMARY KEY ,\n" + " date_ DATE NOT NULL\n" + ");"; stmt.execute ( sql ); // Insert row. sql = "INSERT INTO test_ ( date_ ) " + "VALUES (?) ;"; try ( PreparedStatement preparedStatement = conn.prepareStatement ( sql ) ; ) { LocalDate today = LocalDate.now ( ZoneId.of ( "America/Montreal" ) );
以上是如何使用 JDBC 从 H2 数据库插入和检索 java.time.LocalDate 对象?的详细内容。更多信息请关注PHP中文网其他相关文章!