Java Date - 插入数据库

zSy*_*sis 14 java sql date

我需要找到一种方法将带有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.Datejava.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"的人,你的原始实现就会出现问题).


Osc*_*Ryz 8

PreparedStatement的

你绝对应该使用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)


Bri*_*ian 7

当然,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)

  • @zSyspo:是String s = new SimpleDateFormat("dd/MM/yyyy").format(aDate); 会做 (3认同)

Bas*_*que 7

OscarRyz 的答案是正确的,应该是被接受的答案。但现在这个答案已经过时了。

\n\n

java.time

\n\n

在 Java 8 及更高版本中,我们有新的java.time 包(受到Joda-Time的启发,由JSR 310定义,带有教程,由ThreeTen-Extra项目扩展)。

\n\n

避免旧的日期时间类

\n\n

旧的 java.util.Date/.Calendar、SimpleDateFormat 和 java.sql.Date 类是一团混乱。一方面,juDate 有日期时间,而 jsDate 仅包含日期,没有时间。哦,除了 jsDate 只是假装没有时间。作为 juDate 的子类,jsDate 继承了一天中的时间,但自动将该时间调整为午夜 ( 00:00:00.000)。令人困惑?是的。坦率地说,这是一个糟糕的黑客行为。

\n\n

出于这个以及更多的原因,应该避免那些旧的类,仅在最后的手段下使用。尽可能使用 java.time,并使用Joda-Time作为后备。

\n\n

LocalDate

\n\n

在 java.time 中,该类LocalDate干净地表示仅日期值,没有任何时间或时区。这就是我们这个 Question\xe2\x80\x99s 解决方案所需要的。

\n\n

为了获取 LocalDate 对象,我们解析输入字符串。SimpleDateFormat但java.time没有使用旧类,而是在java.time.format 包DateTimeFormatter中提供了一个新类。

\n\n
String input = "01/01/2009" ;\nDateTimeFormatter formatter = DateTimeFormatter.ofPattern( "MM/dd/yyyy" ) ;\nLocalDate localDate = LocalDate.parse( input, formatter ) ;\n
Run Code Online (Sandbox Code Playgroud)\n\n

JDBC 4.2或更高版本兼容的 JDBC 驱动程序可以通过PreparedStatement::setObjectResultSet::getObject方法直接使用 java.time 类型。

\n\n
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.*. \n
Run Code Online (Sandbox Code Playgroud)\n\n

但在您拥有这样一个更新的 JDBC 驱动程序之前,请回退到使用java.sql.Date类。java.sql.Date幸运的是, Java 8 赋予了这个旧类一个新的方便的转换静态方法, valueOf( LocalDate ).

\n\n

在OscarRyz 的兄弟 Answer的示例代码中,将其“sqlDate =”行替换为以下行:

\n\n
java.sql.Date sqlDate = java.sql.Date.valueOf( localDate ) ;\n
Run Code Online (Sandbox Code Playgroud)\n