java.util.Date vs java.sql.Date

2022-08-31 04:19:33

java.util.Datevs : 何时使用哪个以及为什么?java.sql.Date


答案 1

恭喜你,你已经用JDBC击中了我最喜欢的宠物烦恼:日期类处理。

基本上,数据库通常支持至少种形式的日期时间字段,即日期,时间和时间戳。它们中的每一个在JDBC中都有一个对应的类,并且每个类都扩展java.util.Date。这三种方法的快速语义如下:

  • java.sql.Date对应于SQL DATE,这意味着它存储年,月和日,而小时,分钟,秒和毫秒被忽略。此外,与时区无关。sql.Date
  • java.sql.Time对应于SQL TIME,应该很明显,它只包含有关小时,分钟,秒和毫秒的信息。
  • java.sql.Timestamp 对应于 SQL TIMESTAMP,它是纳秒的精确日期(请注意,util.日期仅支持毫秒!具有可定制的精度。

使用与这三种类型相关的 JDBC 驱动程序时,最常见的错误之一是类型处理不正确。这意味着这是特定于时区的,包含当前年份,月份和日期等。sql.Datesql.Time

最后:使用哪一个?

实际上,这取决于字段的 SQL 类型。 具有所有三个值的 setter,即 、 for 和 for 的 setter。PreparedStatement#setDate()sql.Date#setTime()sql.Time#setTimestamp()sql.Timestamp

请注意,如果您使用,您实际上可以为大多数JDBC驱动程序提供正常,这将很高兴地吞噬它,就好像它的类型是正确的,但是当您之后请求数据时,您可能会注意到您实际上缺少一些东西。ps.setObject(fieldIndex, utilDateObject);util.Date

我真的是说根本不应该使用任何日期。

我想说的是,将毫秒/纳秒保存为普通长距离,并将它们转换为您正在使用的任何对象(强制性的joda-time插件)。可以完成的一种黑客方法是将日期组件存储为一个长组件,将时间组件存储为另一个,例如,现在将20100221和154536123。这些幻数可以在SQL查询中使用,并且可以从数据库移植到另一个数据库,并且可以让您完全避免JDBC / Java Date API:s的这一部分。


答案 2

后期编辑:从Java 8开始,你不应该使用,或者你根本无法避免它,而是更喜欢使用java.time包(基于Joda)而不是其他任何东西。如果您不使用Java 8,以下是原始响应:java.util.Datejava.sql.Date


java.sql.Date - 当您调用使用它的库的方法/构造函数时(如JDBC)。否则不会。您不希望为不显式处理 JDBC 的应用程序/模块引入数据库库的依赖项。

java.util.Date - 使用使用它的库时。否则,尽可能少,原因如下:

  • 它是可变的,这意味着每次将其传递给方法或从方法返回时,都必须制作它的防御性副本。

  • 它不能很好地处理日期,这让像你这样的人倒退了,认为日期处理类应该这样做。

  • 现在,因为j.u.D没有很好地完成它的工作,所以引入了可怕的类。它们也是可变的,并且使用起来很糟糕,如果您别无选择,则应避免使用它们。Calendar

  • 有更好的替代方案,比如Joda Time API它甚至可能进入Java 7并成为新的官方日期处理API - 快速搜索说它不会)。

如果你觉得引入像Joda这样的新依赖项是过分的,那么用于对象中的时间戳字段并不是那么糟糕,尽管我自己通常在传递它们时将它们包装在j.u.D中,用于类型安全和文档。long