为什么不在Jdbc中使用java.util.Date?

时间:2012-01-25 19:54:05

标签: java date jdbc

这是一个简单的问题:我知道并且几乎每个人都听说在Jdbc调用中使用java.util.Date进行任何操作都是个坏主意。您应该使用java.sql.Datejava.sql.Timejava.sql.Timestamp。但是,有什么理由不去?我无法找到一篇好的博客文章或SO帖子解释它,除非有时人们看到"奇怪的行为"。

谢谢!

修改

所以,我看过this post。是的,该帖子的唯一部分是我的问题的答案

  

...对于大多数JDBC驱动程序来说,它们会愉快地吞噬它,就像它一样   正确的类型,但是当您之后请求数据时,您可以   请注意,你实际上缺少了东西。

但是,这并没有真正回答为什么

4 个答案:

答案 0 :(得分:16)

好的,所以在阅读了所有答案中的所有信息,以及评论中指出的其他帖子等等之后,我决定总结一下我学到的东西:

设置:

从我所看到的,有三层

JDBC wrapper calls (e.g. Spring's SimpleJdbcTemplate)
|
|
Raw JDBC calls (e.g. PreparedStatement)
|
|
JDBC driver (e.g. Oracle)

第一个原因

许多JDBC类包装器(例如Spring着名的SimpleJdbcTemplate)允许您在执行SQL语句时将Map<String, Object>作为参数映射。这非常简单,因为当它在引擎盖下使用原始JDBC时,它会将对象的所有转换交给正确的java.sql.*类型。第一个问题在于:如果您有以下内容会发生什么:

Map<String, Object> paramMap = new HashMap<String,Object>();
paramMap.put("p_some_data", new java.util.Date());

Spring将它转换为什么?一个java.sql.Date?一个java.sql.Timestamp?一个java.sql.Time?或者甚至把它投到java.lang.Object?正如this answer to a different questionanother fellow here中@BalusC所解释的那样,这三种java.sql类型之间存在很大差异。所以,第一个原因不使用java.util.Date:您不能依赖框架的内部约定来为您处理转换。

第二个原因

现在,讨论原始JDBC调用,@ The Nail explained,你需要这些java.sql类型来进行JDBC调用,以及he's absolutely right,这是给我的消息。但是,仍有可怕的setObject电话。从阅读the JavaDoc for that call开始,如果给出一个java.util.Date,它会做些什么似乎有些含糊不清。因此,第二个原因不使用它是因为那里含糊不清。

第三个理由

最后,谈谈司机的水平。我可以证明个人经验,有时Spring与Oracle驱动程序一起使用java.util.Date 。有时。然后有时它没有。所以,因为我不知道任何特定驱动程序的任何特定版本将如何处理java.util.Date,所以最好是明确的。这是第三个原因

结论

一般来说,原因似乎是:“JDBC不应该与java.util.Date一起使用。如果你这样做,你就不能确定会发生什么。”这对我来说是一个很好的理由:)

答案 1 :(得分:8)

java.sql.Timestamp

  

java.util.Date的瘦包装器,允许JDBC API将其标识为SQL TIMESTAMP值。它增加了保持SQL TIMESTAMP小数秒值的功能,允许将小数秒的指定精度设置为纳秒。 Timestamp还提供格式化和解析操作,以支持时间戳值的JDBC转义语法。

它是时间戳的精确度(由DB提供),它可以与java.util.Date保持一致。

假设,如果我们使用java.util.Date对象来表示DB中的时间戳值,那么该对象表示的值将不会表示相同的值(如在DB中),因为它不能保持“小数”秒到精度为纳秒“。

答案 2 :(得分:2)

至于Date,这很简单:PreparedStatement.setDate需要java.sql.Date,而不是java.util.Date

您可以像这样转换java.util.Datejava.sql.Date

java.sql.Date sqlDate = new java.sql.Date(date.getTime());

答案 3 :(得分:2)

 java.util.Date 

表示一般的DateTime Value.Basically是Java Type。

 java.sql.Date

特定用于将Java Object对象模型映射到SQL数据类型,该数据类型用于SQL数据。 (Sql Type不是Java Type)。