在PreparedStatement中使用setDate
为了使我们的代码更加标准化,我们被要求将我们的SQLvariables硬编码为SQL语句的所有地方改为准备语句,然后绑定variables。
不过,我正面临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() ? 
  ❐使用java.sql.Date 
 如果你的表有一个DATEtypes的列: 
- 
java.lang.Stringjava.sql.Date.valueOf(java.lang.String)方法接收到一个string,表示格式为yyyy-[m]m-[d]d。 例如:ps.setDate(2, java.sql.Date.valueOf("2013-09-04"));
- 
java.util.Date假设你有一个types为 java.util.Date的variablesendDate,你可以这样进行转换:ps.setDate(2, new java.sql.Date(endDate.getTime());
- 
当前 如果你想插入当前date: 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 
 如果您的表有一个TIMESTAMP或DATETIMEtypes的列: 
- 
java.lang.Stringjava.sql.Timestamp.valueOf(java.lang.String)方法接收到表示date的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假设你有一个types为 java.util.Date的variablesendDate,你可以这样进行转换: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()));
TL;博士
 myPreparedStatement.setObject( … , myLocalDate ) 
…和…
 myResultSet.getObject( … , LocalDate.class ) 
细节
Vargas的答案是提到java.timetypes,但只涉及转换为java.sql.Date。 如果您的驱动程序已更新,则无需转换。
java.time
  java.time框架内置于Java 8及更高版本中。 这些类取代了旧的麻烦date时间类,如java.util.Date , .Calendar和java.text.SimpleDateFormat 。  Joda-Time团队还build议迁移到java.time。 
要了解更多信息,请参阅Oracle教程 。 并search堆栈溢出了很多例子和解释。
大部分的java.timefunction在ThreeTen- Backport中被移植到Java 6&7中,并在ThreeTenABP中进一步适应Android。
 LocalDate 
 在java.time中, java.time.LocalDate类表示没有时间和没有时区的只有date的值。 
 如果使用符合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.timetypes,请回退到转换为java.sqltypes。 但是最小化它们的使用,只使用java.timetypes的业务逻辑。
 新的方法已被添加到旧的类转换为/从java.timetypes。 对于java.sql.Date请参阅valueOf和toLocalDate方法。 
 java.sql.Date sqlDate = java.sql.Date.valueOf( localDate ); 
…和…
 LocalDate localDate = sqlDate.toLocalDate(); 
占位符值
 请谨慎使用作为您的问题代码中显示的占位符值。 并不是所有的数据库和其他软件都能及时处理。 我build议使用像1970年,1970年1月1 1970-01-01用的Unix / Posix时代的参考date 。 
 LocalDate EPOCH_DATE = LocalDate.ofEpochDay( 0 ); // 1970-01-01 is day 0 in Epoch counting. 
 你遇到的问题是,你从一个格式化的java.util.Date传递不兼容的格式来构造一个java.sql.Date的实例,当使用valueOf()它们的行为不同,因为它们使用不同的格式。 
 我也可以看到你的目标是持续时间和分钟,而且我认为你最好把数据types改为java.sql.Timestamp ,它支持小时和分钟,并且把你的数据库字段改为DATETIME或类似的(取决于您的数据库供应商)。 
 无论如何,如果你想从java.util.Date to java.sql.Date更改java.util.Date to java.sql.Date ,我build议使用 
 java.util.Date date = Calendar.getInstance().getTime(); java.sql.Date sqlDate = new java.sql.Date(date.getTime()); // ... more code here prs.setDate(sqlDate); 
 该文档明确指出, java.sql.Date将抛出: 
IllegalArgumentException– 如果给定的date不是JDBCdate转义格式(yyyy-[m]m-[d]d)
 你也不需要把date转换成String然后转换成sql.date ,这似乎是多余的(并且容易出错)。 相反,您可以: 
 java.sql.Date sqlDate := new java.sql.Date(now.getTime()); prs.setDate(2, sqlDate); prs.setDate(3, sqlDate); 
如果要将当前date添加到数据库中,我将避免在Java中计算date。 如果客户端configuration错误,时间错误,时区错误等,在Java(客户端)上确定“现在”会导致数据库中可能的不一致。相反,date可以在服务器端设置为方式如下:
 requestSQL = "INSERT INTO CREDIT_REQ_TITLE_ORDER (" + "REQUEST_ID, ORDER_DT, FOLLOWUP_DT) " + "VALUES(?, SYSDATE, SYSDATE + 30)"; ... prs.setInt(1, new Integer(requestID)); 
 这样,只需要一个绑定参数,并且在服务器端计算date将是一致的。 更好的做法是将一个插入触发器添加到CREDIT_REQ_TITLE_ORDER并让触发器插入date。 这可以帮助强化不同客户端应用程序之间的一致性(例如,有人试图通过sqlplus进行修复。 
不知道,但我认为你正在寻找的是从string创build一个java.util.Date,然后将该java.util.Date转换为java.sql.Date。
尝试这个:
 private static java.sql.Date getCurrentDate(String date) { java.util.Date today; java.sql.Date rv = null; try { SimpleDateFormat format = new SimpleDateFormat("dd-MM-yyyy"); today = format.parse(date); rv = new java.sql.Date(today.getTime()); System.out.println(rv.getTime()); } catch (Exception e) { System.out.println("Exception: " + e.getMessage()); } finally { return rv; } } 
将为setDate()返回一个java.sql.Date对象;
上面的function会打印出一个长长的值:
1375934400000