java.util.Date vs . java.sql.Date:什么时候使用哪个,为什么?


当前回答

date类在Java中表示一个特定的时刻(例如,.g。, 2013 Nov 25 16:30:45精确到毫秒),但是DB中的DATE数据类型只表示一个日期(例如,2013 Nov 25)。为了防止您错误地向DB提供Java .util. date对象,Java不允许您直接将SQL参数设置为Java .util. date:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work

但是它仍然允许您通过强制/意图来这样做(然后DB驱动程序将忽略小时和分钟)。这是通过java.sql.Date类完成的:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work

java.sql.Date对象可以存储时刻(因此很容易从java.util.Date构造它),但如果您试图询问它的小时数(以强制其仅为日期的概念),则会抛出异常。DB驱动程序应该能够识别这个类,并且只使用0表示小时数。试试这个:

public static void main(String[] args) {
  java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
  java.sql.Date d2 = new java.sql.Date(12345);
  System.out.println(d1.getHours());
  System.out.println(d2.getHours());
}

其他回答

祝贺您,您已经解决了JDBC最让我头疼的问题:日期类处理。

基本上,数据库通常至少支持三种形式的datetime字段,即date、time和timestamp。它们中的每一个在JDBC中都有一个对应的类,并且它们都扩展了java.util.Date。这三者的快速语义如下:

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

在使用与这三种类型相关的JDBC驱动程序时,最常见的错误之一是这些类型被错误地处理。这意味着sql。Date是特定于时区的,sql。时间包含当前的年、月、日等等。

最后:用哪一个呢?

实际上这取决于字段的SQL类型。PreparedStatement有三个值的设置器,#setDate()是sql的设置器。日期,#setTime() sql。sql.Timestamp的时间和#setTimestamp()。

请注意,如果您使用ps.setObject(fieldIndex, utilDateObject);你可以给出一个正常的util。大多数JDBC驱动程序会很高兴地处理它,就好像它是正确的类型一样,但是当您随后请求数据时,您可能会注意到您实际上遗漏了一些东西。

我的意思是,这些日期都不应该使用。

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

我有同样的问题,我发现插入当前日期到一个准备好的语句的最简单的方法是:

preparedStatement.setDate(1, new java.sql.Date(new java.util.Date().getTime()));

使用java.sql.Date的唯一时间是在PreparedStatement.setDate中。否则,使用java.util.Date。它告诉ResultSet。getDate返回一个java.sql.Date,但它可以直接分配给java.util.Date。

date类在Java中表示一个特定的时刻(例如,.g。, 2013 Nov 25 16:30:45精确到毫秒),但是DB中的DATE数据类型只表示一个日期(例如,2013 Nov 25)。为了防止您错误地向DB提供Java .util. date对象,Java不允许您直接将SQL参数设置为Java .util. date:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, d); //will not work

但是它仍然允许您通过强制/意图来这样做(然后DB驱动程序将忽略小时和分钟)。这是通过java.sql.Date类完成的:

PreparedStatement st = ...
java.util.Date d = ...
st.setDate(1, new java.sql.Date(d.getTime())); //will work

java.sql.Date对象可以存储时刻(因此很容易从java.util.Date构造它),但如果您试图询问它的小时数(以强制其仅为日期的概念),则会抛出异常。DB驱动程序应该能够识别这个类,并且只使用0表示小时数。试试这个:

public static void main(String[] args) {
  java.util.Date d1 = new java.util.Date(12345);//ms since 1970 Jan 1 midnight
  java.sql.Date d2 = new java.sql.Date(12345);
  System.out.println(d1.getHours());
  System.out.println(d2.getHours());
}

date表示精确到毫秒的特定时刻。它表示不带时区的日期和时间信息。date类实现了可序列化、可克隆和可比较的接口。它被java.sql继承。Date、java.sql.Time和java.sql.Timestamp接口。

java.sql.Date扩展了java.util.Date类,它表示没有时间信息的日期,只应该在处理数据库时使用。为了符合SQL DATE的定义,java.sql.Date实例包装的毫秒值必须“规范化”,方法是在实例关联的特定时区中将小时、分钟、秒和毫秒设置为零。

它继承了java.util.Date的所有公共方法,如getHours()、getMinutes()、getSeconds()、setHours()、setMinutes()、setSeconds()。由于java.sql.Date不存储时间信息,它覆盖了java.util. date中的所有时间操作,并且所有这些方法在调用时会抛出java.lang.IllegalArgumentException,这从它们的实现细节中可以明显看到。