【问题标题】:Storing a Date value with JDBC and Postgres使用 JDBC 和 Postgres 存储日期值
【发布时间】:2018-07-27 12:16:04
【问题描述】:

我已经使用 java 与 NetBeans 制作了一个公式。

在那个公式中,我有一个字段 JDateChooser。问题是当我尝试将该值插入 Postgres 数据库时:

public void insertarDatos(Usuario u){

    try {
        String sql = "INSERT INTO usuario( dni, nombre, apellidos, correo, "
                + "telefono, usuario, clave, fecha, foto)\n"
                + "VALUES (?, ?, ?, ?, ?, ?, ?, '"+u.getFecha()+"', ?);";
        PreparedStatement ps=con.con.prepareStatement(sql);
        ps.setString(1, u.getDni());
        ps.setString(2, u.getNombre());
        ps.setString(3, u.getApellidos());
        ps.setString(4, u.getCorreo());
        ps.setString(5, u.getTelefono());
        ps.setString(6, u.getUsuario());
        ps.setString(7, u.getClave());

        ps.setBinaryStream(8, u.getFis(), u.getLongitudBytes());
        boolean ejecucion=con.ejecutarSQL(ps);
        if(ejecucion==true){
            JOptionPane.showMessageDialog(null, "usuario correctamente"
                    + "registrado");
        }else if(ejecucion==false){
            JOptionPane.showMessageDialog(null, "error insertar usuario");
        }

    } catch (Exception e) {
        System.out.println("error al insertar: " + e);
    }
}

然后Java给我一个这样的错误:

error al ejecutar: org.postgresql.util.PSQLException: ERROR: la sintaxis de entrada no es válida para Tipo date: «null»

但是,如果我在 Postgres 编辑器中进行查询,它可以正常工作。

【问题讨论】:

  • 不要将日期(或数字)作为字符串传递。传递LocalDate 的实例(使用setObject())或至少使用setDate()java.sql.Date 的实例
  • 当您(正确地)为所有其他值使用参数占位符时,为什么要将 u.getFecha() 嵌入到 SQL 命令文本中?

标签: java sql postgresql jdbc


【解决方案1】:

数据库中日期列的数据类型是什么?它是否以日期格式或字符串存储日期?如果它以日期格式存储日期,您应该将从 JDateChooser 获得的日期转换为 java.sql.Date。您必须这样做,因为 JDateChooser 返回 java.util.Date 并且数据库应该使用 java.sql.date。尝试像这样转换它:

java.util.Date datum = jDateChooser1.getDate();
java.sql.Date sqldate = new java.sql.Date(datum.getTime());

【讨论】:

  • 我的字段“fecha”(英文日期)是 postgres 数据库中的日期。谢谢朋友,我会检查你的解决方案,如果可以的话我会告诉你
  • 使用日期对象作为日期是个好主意。使用过时的java.util.Datejava.sql.Date 更少。今天使用来自 java.time(现代 Java 日期和时间 API)的 LocalDate 来表示没有时间的日期。然后像ps.setObject(7, u.getFecha()); 这样getFecha 返回LocalDate
  • 如果我写:java.util.Date datum = jDateChooser1.getDate(); java.sql.Date sqldate = new java.sql.Date(datum.getTime());然后它返回:error al iniciar: java.lang.NullPointerException
  • 我正在编码 LocalDate fec = jdateFecha.getDate();它返回一个错误:日期无法转换为 LocaDate
【解决方案2】:

java.time

避免使用麻烦的旧日期时间类,例如 java.util.Datejava.util.Calendarjava.sql.Datejava.sql.Timestamp

仅使用 java.time 类。具体来说,Instant 类替换了java.util.Datejava.sql.TimestampInstant 解析到纳秒级,对于 Postgres 的微秒级解析来说绰绰有余。

要与尚未更新到java.time 的旧代码互操作,请转换。查看添加到旧类的新方法。

Instant instant = myJavaUtilDate.toInstant() ;

……和……

java.util.Date myJavaUtilDate = java.util.Date.from( instant ) ;

JDBC 4.2

不要将日期时间值作为文本传递或获取到数据库中。

从 JDBC 4.2 起,我们可以直接与数据库交换 java.time 对象。

致电PreparedStatement::setObjectResultSet::getObject

搜索堆栈溢出

这个话题已经在 Stack Overflow 上讨论过很多次了。搜索更多信息和示例。


关于java.time

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

Joda-Time 项目现在位于maintenance mode,建议迁移到java.time 类。

要了解更多信息,请参阅Oracle Tutorial。并在 Stack Overflow 上搜索许多示例和解释。规格为JSR 310

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

从哪里获得 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是未来可能添加到 java.time 的试验场。您可以在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore

【讨论】:

  • 您的回答并没有真正解决问题,您只是发布了一些您在回答涉及 JDBC 和日期的问题时似乎经常发布的片段。我不认为这对这种形式真的有帮助。特别是不像你的回答建议使用Instant,它甚至不被JDBC支持(至少,不是setObject的参数)。
【解决方案3】:

如果我写: java.util.Date 数据 = jDateChooser1.getDate(); java.sql.Date sqldate = new java.sql.Date(datum.getTime());

然后它返回: 初始错误:java.lang.NullPointerException

当我写:LocalDate fec = jdateFecha.getDate(); 它返回给我一个错误: 日期无法转换为 LocaDate -

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    • 1970-01-01
    相关资源
    最近更新 更多