【问题标题】:Cannot store Date variable in database in Java无法在Java中将日期变量存储在数据库中
【发布时间】:2013-07-02 10:30:09
【问题描述】:

我试图在数据库中保留用户的最后登录日期。以下是必要的部分:

在我的登录页面中,我创建了一个 Date 对象并将其放入我的会话中,我导入 java.util.Date

<% 
Calendar c = Calendar.getInstance();

Date l = new Date(c.get(Calendar.YEAR),c.get(Calendar.MONTH),c.get(Calendar.DAY_OF_MONTH),c.get(Calendar.HOUR),c.get(Calendar.MINUTE)); //the midnight, that's the first second of the day.


//Globals.customer.lastlogin=l;
session.setAttribute("lastlogin", l);   %>

然后当登录成功时,我在我的servlet中更新我的数据库,当点击登录按钮时这个servlet被调用:

try {
    int result=-1;
    PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(
            "UPDATE users set lastlogin='"+(Date)session.getAttribute("lastlogin")+"' where username='"+session.getAttribute("username")+"'");


        result= checkDB.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

我将 lastlogin 作为一个 Date 变量保存在我的数据库中。但是尝试更新上次登录时出现以下错误:

com.mysql.jdbc.MysqlDataTruncation: Data truncation: Incorrect date value: 'Wed Jul 02 05:49:00 VET 3913' for column 'lastlogin' at row 1
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2936)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1601)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1710)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2436)
at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1402)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1694)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1608)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1593)
at classes.LoginServlet.service(LoginServlet.java:94)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:723)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
at java.lang.Thread.run(Thread.java:662)

谁能帮我解决这个问题?谢谢

【问题讨论】:

标签: java database jsp jakarta-ee servlets


【解决方案1】:

您应该利用 PreparedStatement 并使用 ?参数的占位符。

PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(
                "UPDATE users set lastlogin=? where username=?");

checkDB.setDate(1, (Date)session.getAttribute("lastlogin"));
checkDB.setString(2, session.getAttribute("username"));

这将根据您的数据库的要求正确格式化日期。

【讨论】:

  • 谢谢,但是通过使用 java.sql.date 我无法存储小时和分钟,有什么办法可以做到这一点?
  • 使用 java.sql.Timestamp 存储日期和时间。 java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp(utilDate.getTime()); 然后使用checkDB.setTimestamp 而不是checkDB.setDate
【解决方案2】:

您可能需要检查您使用的是 java.sql.Date 还是 java.util.Date。使用 java.sql.date 避免任何兼容性问题。

【讨论】:

  • 我正在使用 java.util.date,但是当我使用 sql.date 时,我无法存储分钟和小时,对吗?我该怎么做?
  • @constructor 如果可以的话,请考虑在数据库中以毫秒为单位存储时间,并在阅读时对其进行格式化。
【解决方案3】:

您应该使用问号来参数化 PreparedStatements。

试试这个(确保日期是 java.sql.Date):

String getUserLastLogin = "UPDATE users set lastlogin=? where username=?";
Date lastLogin = (Date)session.getAttribute("lastlogin");
String username = session.getAttribute("username");

PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(getUserLastLogin);
checkDB.setDate(1, lastLogin);
checkDB.setString(2, username);

result= checkDB.executeUpdate();

另外,在 catch 之后添加一个 finally 块,确保关闭 PreparedStatement,然后关闭 Connection,这样就不会留下打开的数据库连接。

【讨论】:

  • 谢谢,但是通过使用 java.sql.date 我无法存储小时和分钟,有什么办法可以做到这一点吗?
  • 使用日历,然后在需要将其存储在数据库中时将其转换为日期。
  • 是的,但这可以在 java.util.date 中完成,java.sql.date 没有合适的构造函数,或者我不知道
  • 对不起,您应该使用 java.sql.Timestamp。
【解决方案4】:
try {
    int result=-1;
     String dateToInsert = new SimpleDateFormat(yyyy-MM-dd).parse((Date)session.getAttribute("lastlogin"));
    PreparedStatement checkDB = (PreparedStatement) con.prepareStatement(
            "UPDATE users set lastlogin='"+dateToInsert+"' where username='"+session.getAttribute("username")+"'");


        result= checkDB.executeUpdate();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

试试这个。 问题是您的会话中有日期对象,其格式无法插入 DB。日期应采用与 D.B 兼容的格式

【讨论】:

    【解决方案5】:

    您还需要拨打java.sql.timestamp 来获取时间...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-31
      • 2014-05-04
      • 1970-01-01
      • 1970-01-01
      • 2019-12-19
      相关资源
      最近更新 更多