我需要找到一种方法将带有java.util.Date字段的记录插入到数据库中,并且我被卡住了.
有谁知道我怎么做到这一点?现在我有类似的东西.
java.util.Date myDate = new java.util.Date("01/01/2009");
sb.append("INSERT INTO USERS");
sb.append("(USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE) ");
sb.append("VALUES ( ");
sb.append(" '" + userId + "'");
sb.append(", '" + myUser.GetFirstname() + "' ");
sb.append(", '" + myUser.GetLastname() + "' ");
sb.append(", '" + myUser.GetSex() + "' ");
sb.append(", '" + myDate + "'");
sb.append(")");
Util.executeUpdate(sb.toString());
Run Code Online (Sandbox Code Playgroud)
但是,当我运行这样的东西时,我得到错误:日期时间值的字符串表示的语法不正确.
下面是sql语句的样子:
INSERT INTO USERS (USER_ID
, FIRST_NAME
, LAST_NAME
, SEX
, CRDATE)
VALUES (
'user'
, 'FirstTest'
, 'LastTest'
, 'M'
, 'Thu Jan 01 00:00:00 CST 2009')
Run Code Online (Sandbox Code Playgroud)
谢谢
Jac*_*eow 13
在我回答你的问题之前,我想提一下你应该考虑使用某种ORM解决方案(例如,Hibernate),它包含在数据访问层之后.你在做什么似乎是非常反OO.我承认你不知道你的代码的其余部分是什么样的,但一般来说,如果你开始看到自己使用了很多实用程序类,那么你可能采取过于结构化的方法.
要像其他人提到的那样回答您的问题,请查看java.sql.PreparedStatement并使用java.sql.Date或java.sql.Timestamp.有点像(尽可能多地使用原始代码,你可能想要更改它):
java.util.Date myDate = new java.util.Date("10/10/2009");
java.sql.Date sqlDate = new java.sql.Date(myDate.getTime());
sb.append("INSERT INTO USERS");
sb.append("(USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE) ");
sb.append("VALUES ( ");
sb.append("?, ?, ?, ?, ?");
sb.append(")");
Connection conn = ...;// you'll have to get this connection somehow
PreparedStatement stmt = conn.prepareStatement(sb.toString());
stmt.setString(1, userId);
stmt.setString(2, myUser.GetFirstName());
stmt.setString(3, myUser.GetLastName());
stmt.setString(4, myUser.GetSex());
stmt.setDate(5, sqlDate);
stmt.executeUpdate(); // optionally check the return value of this call
Run Code Online (Sandbox Code Playgroud)
这种方法的另一个好处是它会自动为你逃脱你的字符串(例如,如果要插入姓氏为"O'Brien"的人,你的原始实现就会出现问题).
你绝对应该使用PreparedStatement.(教程)
这样你就可以调用:
pstmt.setDate( 1, aDate );
Run Code Online (Sandbox Code Playgroud)
该JDBC驱动程序将做日期时间处理适合您的特定数据库.
此外,PreparedStatement停止任何SQL注入黑客攻击 - 非常重要!(幽默)
它应该如下所示:
SimpleDateFormat format = new SimpleDateFormat( "MM/dd/yyyy" ); // United States style of format.
java.util.Date myDate = format.parse( "10/10/2009" ); // Notice the ".util." of package name.
PreparedStatement pstmt = connection.prepareStatement(
"INSERT INTO USERS ( USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE ) " +
" values (?, ?, ?, ?, ? )");
pstmt.setString( 1, userId );
pstmt.setString( 3, myUser.getLastName() );
pstmt.setString( 2, myUser.getFirstName() ); // please use "getFir…" instead of "GetFir…", per Java conventions.
pstmt.setString( 4, myUser.getSex() );
java.sql.Date sqlDate = new java.sql.Date( myDate.getTime() ); // Notice the ".sql." (not "util") in package name.
pstmt.setDate( 5, sqlDate );
Run Code Online (Sandbox Code Playgroud)
就是这样,JDBC驱动程序将为您创建正确的SQL语法.
检索Date对象时,可以使用SimpleDateFormat创建日期时间值的格式化字符串表示形式.
这是一个快速示例行,但搜索StackOverflow 还有更多.
String s = new SimpleDateFormat("dd/MM/yyyy").format( aDate );
Run Code Online (Sandbox Code Playgroud)
当然,PreparedStatement将使您的代码更好,但要回答您的问题,您需要告诉DBMS您的字符串表示形式的日期.在Oracle(您没有命名数据库供应商)中,字符串日期将转换为Date使用以下TO_DATE()函数:
INSERT INTO TABLE_NAME(
date_column
)values(
TO_DATE('06/06/2006', 'mm/dd/yyyy')
)
Run Code Online (Sandbox Code Playgroud)
OscarRyz 的答案是正确的,应该是被接受的答案。但现在这个答案已经过时了。
\n\n在 Java 8 及更高版本中,我们有新的java.time 包(受到Joda-Time的启发,由JSR 310定义,带有教程,由ThreeTen-Extra项目扩展)。
\n\n旧的 java.util.Date/.Calendar、SimpleDateFormat 和 java.sql.Date 类是一团混乱。一方面,juDate 有日期和时间,而 jsDate 仅包含日期,没有时间。哦,除了 jsDate 只是假装没有时间。作为 juDate 的子类,jsDate 继承了一天中的时间,但自动将该时间调整为午夜 ( 00:00:00.000)。令人困惑?是的。坦率地说,这是一个糟糕的黑客行为。
出于这个以及更多的原因,应该避免那些旧的类,仅在最后的手段下使用。尽可能使用 java.time,并使用Joda-Time作为后备。
\n\nLocalDate在 java.time 中,该类LocalDate干净地表示仅日期值,没有任何时间或时区。这就是我们这个 Question\xe2\x80\x99s 解决方案所需要的。
为了获取 LocalDate 对象,我们解析输入字符串。SimpleDateFormat但java.time没有使用旧类,而是在java.time.format 包DateTimeFormatter中提供了一个新类。
String input = "01/01/2009" ;\nDateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ;\nLocalDate localDate = LocalDate.parse( input, formatter ) ;\nRun Code Online (Sandbox Code Playgroud)\n\n与JDBC 4.2或更高版本兼容的 JDBC 驱动程序可以通过PreparedStatement::setObject和ResultSet::getObject方法直接使用 java.time 类型。
PreparedStatement pstmt = connection.prepareStatement(\n "INSERT INTO USERS ( USER_ID, FIRST_NAME, LAST_NAME, SEX, DATE ) " +\n " VALUES (?, ?, ?, ?, ? )");\n\npstmt.setString( 1, userId );\npstmt.setString( 3, myUser.getLastName() ); \npstmt.setString( 2, myUser.getFirstName() ); // please use "getFir\xe2\x80\xa6" instead of "GetFir\xe2\x80\xa6", per Java conventions.\npstmt.setString( 4, myUser.getSex() );\npstmt.setObject( 5, localDate ) ; // Pass java.time object directly, without any need for java.sql.*. \nRun Code Online (Sandbox Code Playgroud)\n\n但在您拥有这样一个更新的 JDBC 驱动程序之前,请回退到使用java.sql.Date类。java.sql.Date幸运的是, Java 8 赋予了这个旧类一个新的方便的转换静态方法, valueOf( LocalDate ).
在OscarRyz 的兄弟 Answer的示例代码中,将其“sqlDate =”行替换为以下行:
\n\njava.sql.Date sqlDate = java.sql.Date.valueOf( localDate ) ;\nRun Code Online (Sandbox Code Playgroud)\n