在 PreparedStatement 中使用 setDatetl;博士详java.timeLocalDate在 JDBC 4.2 之前,转换占位符值关于 java.time

2022-08-31 15:15:55

为了使我们的代码更加标准,我们被要求将所有将SQL变量硬编码的地方更改为预准备语句并绑定变量。

但是,我遇到了.setDate()

代码如下:

        DateFormat dateFormatYMD = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
        DateFormat dateFormatMDY = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
        Date now = new Date();
        String vDateYMD = dateFormatYMD.format(now);
        String vDateMDY = dateFormatMDY.format(now);
        String vDateMDYSQL =  vDateMDY ;
        java.sql.Date date = new java.sql.Date(0000-00-00);

   requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (REQUEST_ID," + 
                " ORDER_DT, FOLLOWUP_DT) " +  "values(?,?,?,)";


                prs = conn.prepareStatement(requestSQL);

                prs.setInt(1,new Integer(requestID));

                prs.setDate(2,date.valueOf(vDateMDYSQL));
                prs.setDate(3,date.valueOf(sqlFollowupDT));

当SQL执行时,我收到此错误:

    java.lang.IllegalArgumentException
    at java.sql.Date.valueOf(Date.java:138)
    at com.cmsi.eValuate.TAF.TAFModuleMain.CallTAF(TAFModuleMain.java:1211)

我应该使用 ?setString()to_date()


答案 1

❐ 使用java.sql.Date

如果您的表具有以下类型的列:DATE

  • java.lang.String

    方法 java.sql.Date.valueOf(java.lang.String) 接收到一个字符串,该字符串以 .例如:yyyy-[m]m-[d]d

    ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
    
  • java.util.Date

    假设您有一个类型的变量,您可以进行以下转换:endDatejava.util.Date

    ps.setDate(2, new java.sql.Date(endDate.getTime());
    
  • 当前

    如果要插入当前日期:

    ps.setDate(2, new java.sql.Date(System.currentTimeMillis()));
    
    // Since Java 8
    ps.setDate(2, java.sql.Date.valueOf(java.time.LocalDate.now()));
    

❐ 使用java.sql.Timestamp

如果您的表具有类型或的列:TIMESTAMPDATETIME

  • java.lang.String

    方法 java.sql.Timestamp.valueOf(java.lang.String) 接收到一个字符串,该字符串以 格式表示日期。例如:yyyy-[m]m-[d]d hh:mm:ss[.f...]

    ps.setTimestamp(2, java.sql.Timestamp.valueOf("2013-09-04 13:30:00");
    
  • java.util.Date

    假设您有一个类型的变量,您可以进行以下转换:endDatejava.util.Date

    ps.setTimestamp(2, new java.sql.Timestamp(endDate.getTime()));
    
  • 当前

    如果需要当前时间戳:

    ps.setTimestamp(2, new java.sql.Timestamp(System.currentTimeMillis()));
    
    // Since Java 8
    ps.setTimestamp(2, java.sql.Timestamp.from(java.time.Instant.now()));
    ps.setTimestamp(2, java.sql.Timestamp.valueOf(java.time.LocalDateTime.now()));
    

答案 2

tl;博士

对于 JDBC 4.2 或更高版本以及 Java 8 或更高版本:

myPreparedStatement.setObject( … , myLocalDate  )

...和。。。

myResultSet.getObject( … , LocalDate.class )

Vargas的答案很好提到java.time类型,但仅指转换为java.sql.Date。如果您的驱动程序已更新,则无需转换。

java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了旧的麻烦的日期时间类,如 , 、 & 。Joda-Time团队还建议迁移到java.time。java.util.Date.Calendarjava.text.SimpleDateFormat

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。

许多java.time功能在ThreeTen-Backport中向后移植到Java 6和7,并在ThreeTenABP中进一步适应Android。

LocalDate

在 java.time 中,java.time.LocalDate 类表示一个仅日期值,不带一天中的时间和时区。

如果使用符合 JDBC 4.2 或更高版本规范的 JDBC 驱动程序,则无需使用旧的 java.sql.Date 类。您可以通过 PreparedStatement::setObject 和 ResultSet::getObject 直接传入/提取对象到数据库/从数据库获取对象LocalDate

LocalDate localDate = LocalDate.now( ZoneId.of( "America/Montreal" ) );
myPreparedStatement.setObject( 1 , localDate  );

...和。。。

LocalDate localDate = myResultSet.getObject( 1 , LocalDate.class );

在 JDBC 4.2 之前,转换

如果驱动程序无法直接处理 java.time 类型,请回退到转换为 java.sql类型。但是,尽量减少它们的使用,因为您的业务逻辑仅使用java.time类型。

新方法已添加到旧类中,用于与 java.time 类型相互转换。对于 java.sql.Date,请参阅 valueOftoLocalDate 方法。

java.sql.Date sqlDate = java.sql.Date.valueOf( localDate );

...和。。。

LocalDate localDate = sqlDate.toLocalDate();

占位符值

请注意不要用作占位符值,如问题代码中所示。并非所有数据库和其他软件都能处理回溯到那么远的时间。我建议使用类似常用的Unix / Posix纪元参考日期1970年的东西。0000-00-001970-01-01

LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting.

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧日期时间类,如java.util.DateCalendarSimpleDateFormat

Joda-Time 项目现在处于维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。搜索 Stack Overflow 以获取许多示例和解释。规格是JSR 310

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

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过其他类扩展了 java.time。这个项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuarter


推荐