使用PreparedStatement::SetDate
和ResultSet::GetDate
的旧方法适用于遗留的java.sql.date
类型。我想避免使用这些麻烦的旧日期时间类。
通过JDBC驱动程序发送java.time类型的现代方式是什么?
我们有两种通过JDBC交换java.time对象的途径:
遗留的日期时间类,如java.util.date
、java.util.Calendar
,以及相关的java.sql.date
类,如java.sql.date
非常混乱。它们是用设计不佳的黑客方法构建的,事实证明它们是有缺陷的、麻烦的和令人困惑的。尽可能避开他们。现在被java.time类所取代。
myPreparedStatement.setObject ( 1 , myLocalDate ); // Automatic detection and conversion of data type.
LocalDate localDate = myResultSet.getObject ( "my_date_column_" , LocalDate.class );
package com.example.h2localdate;
import java.sql.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.UUID;
/**
* Hello world!
*/
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" ) );
preparedStatement.setObject ( 1, today.minusDays ( 1 ) ); // Yesterday.
preparedStatement.executeUpdate ( );
preparedStatement.setObject ( 1, today ); // Today.
preparedStatement.executeUpdate ( );
preparedStatement.setObject ( 1, today.plusDays ( 1 ) ); // Tomorrow.
preparedStatement.executeUpdate ( );
}
// Query all.
sql = "SELECT * FROM test_";
try ( ResultSet rs = stmt.executeQuery ( sql ) ; ) {
while ( rs.next ( ) ) {
//Retrieve by column name
UUID id = rs.getObject ( "id_", UUID.class ); // Pass the class to be type-safe, rather than casting returned value.
LocalDate localDate = rs.getObject ( "date_", LocalDate.class ); // Ditto, pass class for type-safety.
//Display values
System.out.println ( "id_: " + id + " | date_: " + localDate );
}
}
} catch ( SQLException e ) {
e.printStackTrace ( );
}
}
}
ID_:a4474e79-3e1f-4395-bbba-044423b37b9f日期_:2017-03-27
ID_:5D47BC3D-EBFA-43AB-BBC2-7BB2313B33B0日期_:2017-03-28
对于H2,上面显示的代码是我建议您走的路。但是仅供参考,对于其他还不符合JDBC4.2的数据库,我可以向您展示如何在java.time和java.sql类型之间进行简单的转换。这种转换代码当然可以在H2上运行,如下所示,但现在我们有了上面所示的更简单的方法,这样做是愚蠢的。
java.sql.Date mySqlDate = java.sql.Date.valueOf( myLocalDate );
preparedStatement.setDate ( 1, mySqlDate );
java.sql.Date mySqlDate = myResultSet.getDate( 1 );
LocalDate myLocalDate = mySqlDate.toLocalDate();
package com.example.h2localdate;
import java.sql.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.UUID;
/**
* Hello world!
*/
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" ) );
preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today.minusDays ( 1 ) ) ); // Yesterday.
preparedStatement.executeUpdate ( );
preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today ) ); // Today.
preparedStatement.executeUpdate ( );
preparedStatement.setDate ( 1, java.sql.Date.valueOf ( today.plusDays ( 1 ) ) ); // Tomorrow.
preparedStatement.executeUpdate ( );
}
// Query all.
sql = "SELECT * FROM test_";
try ( ResultSet rs = stmt.executeQuery ( sql ) ; ) {
while ( rs.next ( ) ) {
//Retrieve by column name
UUID id = ( UUID ) rs.getObject ( "id_" ); // Cast the `Object` object to UUID if your driver does not support JDBC 4.2 and its ability to pass the expected return type for type-safety.
java.sql.Date sqlDate = rs.getDate ( "date_" );
LocalDate localDate = sqlDate.toLocalDate (); // Immediately convert into java.time. Mimimize use of java.sql types.
//Display values
System.out.println ( "id_: " + id + " | date_: " + localDate );
}
}
} catch ( SQLException e ) {
e.printStackTrace ( );
}
}
}
package work.basil.example;
import java.sql.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.UUID;
public class LocalDateMin
{
public static void main ( String[] args )
{
LocalDateMin app = new LocalDateMin();
app.doIt();
}
private void doIt ()
{
org.h2.jdbcx.JdbcDataSource ds = new org.h2.jdbcx.JdbcDataSource();
ds.setURL( "jdbc:h2:mem:localdate_min_example_db_;DB_CLOSE_DELAY=-1" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
try (
Connection conn = ds.getConnection() ;
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" ) );
preparedStatement.setObject( 1 , LocalDate.MIN ); // MIN =
preparedStatement.executeUpdate();
}
// Query all.
sql = "SELECT * FROM test_";
try ( ResultSet rs = stmt.executeQuery( sql ) ; )
{
while ( rs.next() )
{
//Retrieve by column name
UUID id = rs.getObject( "id_" , UUID.class ); // Pass the class to be type-safe, rather than casting returned value.
LocalDate localDate = rs.getObject( "date_" , LocalDate.class ); // Ditto, pass class for type-safety.
//Display values
System.out.println( "id_: " + id + " | date_: " + localDate );
}
}
} catch ( SQLException e )
{
e.printStackTrace();
}
}
}
Java.time框架内置在Java8和更高版本中。这些类取代了麻烦的旧的遗留日期时间类,如java.util.date
、Calendar
、&SimpleDateFormat
。
要了解更多信息,请参阅Oracle教程。并搜索堆栈溢出的许多例子和解释。规范是JSR310。
现在处于维护模式的Joda-Time项目建议迁移到java.Time类。
我试图将选中的项目从checkedlistbox保存到我的SQL数据库,并从同一个SQL数据库填充我的checkedlistbox,到目前为止,我能够从checkedlistbox中获取选中项的文本,并将其保存为字符串,然后使用标签显示是否获取选中项的文本及其工作情况,但当我尝试在数据库中插入选中的数据时,我收到一个错误“连接属性尚未初始化”关于ExecuteNonQuery()方法。 这个错误
我有一个SQL函数,它返回一个对象。 上面返回一个对象,比如 我需要从对象中获取单独的值。
问题内容: 我想初始化一个H2数据库,但是我不确定记录是否存在。如果它们不存在,我什么都不愿做,但是如果它们不存在,我想写默认值。 像这样的东西: 问题答案: 以下内容适用于MySQL,PostgreSQL和H2数据库:
问题内容: 我正在尝试使用H2的runscript运行sql脚本。 该表之一包含一个长文本类型,该类型存储了一个xml文档(来自SAP数据库) 因此,Insert语句包含XML的长文本(大约200行XML),虽然很难看,但仍然可以使用。 在SQL解析期间,H2因ArrayOutOfBoundException而崩溃。 插入语句接受的长度是否有限制? 在nsert中,我使用刻度(如mysql中所使用
我正在inMemory数据库中插入数据,当插入数据时,我得到了一个问题, 使用boot、JPA、H2db在内存中插入数据的示例程序 > 创建Pojo并使用JPA注释进行注释 > 配置在app.prop:中 在data.sql文件中添加了给定表 为data.sql中提到的转换添加了名称。 在哪里配置;在Springboot中? 波乔 控制器 错误原因:对名为'in memorydatabaseShu
我有一个CSV文件,如 我正在尝试使用函数将此文件读入数据库,如下所示 出于某种原因,我一直得到< code>SQL错误,指出列数不匹配。 该表是使用Hibernate / GORM创建的,并包含我尝试插入的字段。 select本身似乎可以工作,或者至少在单独执行时不会导致任何错误。我的说法有什么问题?