下面只是解决了时间插入的问题,至于从数据库读书时间的问题,还需要经进一步。
参照下面的帖子 : http://code.google.com/a/eclipselabs.org/p/demo1/wiki/OracleDateTypeHandler

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------

解决:

POJO 中使用new java.sql.Timestamp(new Date().getTime()) , instead of new java.util.Date()

E.g.

reportStatus.setRepstatStarttime(new java.sql.Timestamp(new Date().getTime()));

下面这篇文章也不错,参考

初转自http://blog.feihoo.com/2010/11/jdbc-ibatis-datetimes.html

在此前,遇到过使用Ibatis操作Oracle时时间精度丢失的问题,昨天又遇到JDBC操作MySQL时间字段的问题,从网上看到各种式样的解释这些问题的博文/帖子,但多是雾里看花,不得要领。

  1. 理解JDBC中的时间类型
  2. MySQL与JDBC之间的类型映射
  3. Oracle与JDBC之间的类型映射
  4. Ibatis是怎么处理日期时间类型的
  5. 注释
  6. 参考资料

理解JDBC中的时间类型

java.sql包中包括三个类,Date,Time, 和Timestamp,分别用来表示日期(无时间信息,eg: YYYY-MM-DD),时间(只处理时间,无日期部分, eg: HH:MM:SS)和时间戳(精确到纳秒级别)。在 它们都继承自java.util.Date。java.sql.Date和java.sql.Time都存有一个时间域,该时间域是精确到秒级别的,但是,他们只处理日期或者时间部分。在MySQL Connector/J(v5.1.13)的实现中可以看到,PrepareStatement#setDate 时会将时间重新format成”yyyy-MM-dd”格式。

因为历史遗留以及各种数据库本身的不同,各种JDBC实现中留下了格式各样的花招, 某些特殊场景下不遵照此情况可能也能工作,但不推荐这样做。

你必须根据你的实际需要来选择不同的类型,通常应该选用精确度与相应的数据库字段类型相比相同或者更高的JDBC类型

除此以外,还可以使用java.uitl.Date类型来处理时间。java.util.Date类型是上面各个类型的父类型,JDBC的API大都可以使用。

除此以外,在JDK1.6之前版本的构造java.sql.{Date|Time|TimeStamp}对象时存在性能问题,尤其是在多线程环境下更严重。这个Bug在这里。其原因是java.util.Date的相关方法调用了TimeZone.getDefaultRef(),而此方法是同步方法注1

MySQL的JDBC类型映射

DATE java.sql.Date
DATETIME java.sql.Timestamp
TIMESTAMP[(M)] java.sql.Timestamp
TIME java.sql.Time
YEAR[(2|4)] If yearIsDateType configuration property is set to false, then
the returned object type is java.sql.Short. If set to true (the
default) then an object of type java.sql.Date (with the date
set to January 1st, at midnight).

MySQL的DATETIME、TIMESTAMP两种字段类型的显著区别在于TIMESTAMP的取值在’1970-01-01 00:00:01′ UTC 和 ‘2038-01-19 03:14:07′ UTC之间。

MySQL在时间处理方面也有一个问题,当Datetimes类型的字段的值为0000-00-00时取值方法会得到下面的异常:

Cannot convert value '0000-00-00 00:00:00'from column xx to TIMESTAMP

这个问题的原因在于,MySQL中默认使用0000-00-00等来表示时间的特殊值(参见文档)。而在Java中,并没有一个合适的方式来表示这个时间(因为Java中时间轴上0是1970-01-01 00:00:00),早于这个时间的用负数表示,这个最小的负数在时间轴上是表示不出来的。Connector/J提供了一个属性zeroDateTimeBehavior来解决此问题。

  • exception (the default), which throws an SQLException with an SQLState of S1009.(默认行为)
  • convertToNull, which returns NULL instead of the date.
  • round, which rounds the date to the nearest closest value which is 0001-01-01.

如下所示的jdbc连接将指定该行为转化为null值。

jdbc:mysql://localhost/myDatabase?zeroDateTimeBehavior=convertToNull

Oracle与JDBC之间的类型映射

DATE java.sql.Date
DATE java.sql.Time
TIMESTAMP java.sql.Timestamp

Oracle数据库字段类型主要有DATE、TIMESTAMP。

在9i以后、11g以前的Oracle JDBC驱动中存在一个会丢失DATE类型字段的时间信息的bug,原因是其JDBC驱动将Oracle的Date类型处理为java.sql.Date类型,这就丢失了时间部分(看来对java.sql包下三种时间类型认识不足的问题还很普遍的)。关于这个问题,这篇帖子给出了不错的解释(墙外),此文中的方法适用于11g JDBC以前的各版本驱动。在11g JDBC驱动中,此问题已经解决了,Oracle 11g JDBC驱动的手册中也给出了解释注2

事实上,如果是使用Ibatis,pojo属性的类型设置为java.util.Date,确保 jdbcType不为 DATE或者TIME,则避免了这个bug。因为此时Ibatis会以java.sql.Timestamp来处理该字段。我专门对此做了验证,点此看测试项目源码。

Ibatis是怎么处理日期类型的

注意:本文皆基于ibatis 2.3.4.726源码分析。不过根据我初略观察,Ibatis3也适用,但请遇到问题时有所留意。

在此前工作中碰到Oracle中的Date字段会只剩下日期部分的数据,丢失了,Google发现一些人的解决方法是将JDBCType指定为datetime。有人甚至自己编写一个自定义的TypeHandler来解决这个问题。其实这完全是瞎猫撞上死耗子,那个datetime根本没意义,却歪打正着。一般的错误都是如下的配置(或者是pojo的属性为java.sql.Date类型):

Xml代码  
  1. <sqlMap namespace="Info" >
  2. <resultMap id="Info" class="pojo.Info" >
  3. <result column="INFO_BEGINTIME" property="begin" jdbcType="DATE" />
  4. <result column="INFO_ENDTIME" property="end" jdbcType="DATE" />
  5. </resultMap

此时不论你pojo.Info中的字段类型(或者的javaType属性)是java.util.Date还是java.sql.Date,最终都会丢失数据。实际上,在pojo.Info中的字段类型(或者javaType属性)为java.util.Date时,如果指定jdbcType为DATE或TIME(区分大小写),则将分别得到DateOnlyTypeHandler或TimeOnlyTypeHandler。如果你不指定jdbcType,或者指定一个错误的值,例如datetime,或者xxxx等,都会得到DateTypeHandler(日期时间都会处理)。

如果pojo.Info中的属性类型(或者配置中的javaType属性)是java.sql.Date,则选择处理handler类时不会使用jdbcType,而是根据属性类型得到SqlDateTypeHandler(只包含日期)。

在Ibatis的手册中,指出来jdbcType一般情况下是不用于判断处理方式的注3。大部分情况下是依据javaType或者pojo属性类型来判断处理方式,在少部分无法根据pojo属性类型判断的情况下才使用。如果你用java.util.Date对应到MySQL,则就是这种少数情况之一。因为MySQL可以将多个数据库字段类型映射到java.util.Date,所以需要指定是DATE还是TIME(必须是大写),如果不指定则默认是完整的日期时间(此时按JDBC的timestamp操作)。

针对ibatis对时间的处理,我写了个测试,点此看测试代码。

对于Ibatis操作Date/Time/DateTime,总结如下:

  • 将pojo的属性类型设置为java.sql.Date(或java.sql.Time, java.sql.Timestamp),此时会严格遵循这三种类型的语义。但此方法因存在前文中提到的性能问题,在JDK1.6以前的JDK版本中能少使用就少使用。
  • 如果你想在pojo中使用java.util.Date, 则要注意:
    • 完整的日期时间,要确保jdbcType为空,或为DATE,TIME以外的值
    • 只需要时间,要指定jdbcType=”TIME”
    • 只需要日期,要指定jdbcType=”DATE”

补充一下:当我按照本文所说修改以后,发现仍然存在这个问题,经过仔细排叉,发现我在保存数据的时候,参数类型为java.sql.Date我又看了一下我的insert片断语句为:

Xml代码  
  1. <isNotNull prepend="," property="record.signDate" >
  2. <![CDATA[ SIGN_DATE = #record.signDate:DATE# ]]>
  3. </isNotNull>

我试着将代码修改为:

Xml代码  
  1. <isNotNull prepend="," property="record.signDate" >
  2. <![CDATA[ SIGN_DATE = #record.signDate# ]]>
  3. </isNotNull>

此时再查看debug日志,发现参数类型变为 java.sql.Timestamp问题到此解决,看来不光是resultMap,在insert与update等语句中也要修改。Ps:我的配置文件是由ibator生成

iBatis Date类型时间丢失问题相关推荐

  1. java获取Date类型时间的前3个月,后3个月,前3天,后3天

    java获取Date类型时间的前3个月,后3个月,前3天,后3天 Calendar cal = Calendar.getInstance(); Date date = new Date(); cal. ...

  2. feign date类型时间错误问题

    问题 在feign传输date类型的数据时,在调用方时间正确,而被调用方获取时时间会相差14个小时. 原因 Feign客户端在进行通信时,会将Date类型对象转为String类型,如果这个时间是北京时 ...

  3. @JsonFormat Date类型时间 格式化 注解 使用

    前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家.点击跳转到教程. @JsonFormat注解是一个时间格式化注解,比如我们存储在mysql中的数据是date类型的,当 ...

  4. Date类型时间格式注解

    @ApiModelProperty(value = "生产日期") @DateTimeFormat(pattern = "yyyy-MM-dd") //后端-- ...

  5. 数据库里面date类型时间有时差,时区问题

    SpringBoot项目,mysql数据库 数据库的时区 show variables like "%time_zone%"; 阿里云的数据库 根据网上的资料,可以更改数据库的sy ...

  6. Java 时间 Date类型,Long类型,String类型

    2019独角兽企业重金招聘Python工程师标准>>> Java 日期时间 Date类型,long类型,String类型表现形式的转换 1.java.util.Date类型转换成lo ...

  7. oracle date类型,oracle 日期时间数据类型

    The DATE data type The TIMESTAMP data types: TIMESTAMP TIMESTAMP WITH TIME ZONE TIMESTAMP WITH LOCAL ...

  8. 时间串变成Date类型的数据

    java.text.SimpleDateFormat sf = new java.text.SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); jav ...

  9. oracle时间类型转化成java对象_Oracle数据库date类型与Java中Date的联系与转化

    以下是对Java中的日期对象与Oracle中的日期之间的区别与联系做点说明,以期对大家有所帮助. new Date():分配 Date 对象并初始化此对象,以表示分配它的时间(精确到毫秒),就是系统当 ...

最新文章

  1. 网络模型--Squeeze-and-Excitation Networks
  2. Xilinx FPGA开发工具总结
  3. Android的全屏活动?
  4. php preg_replace 正则替换图片路径
  5. pip install python -32_pip安装python模块方法
  6. 常用数据库连接池 (DBCP、c3p0、Druid) 配置说明
  7. Packet Tracer 5.0实验(四) 利用三层交换机实现VLAN间路由
  8. Linux下获取CPUID、硬盘序列号与MAC地址
  9. HTML DOM教程 19-HTML DOM Button 对象
  10. javascript-分支与循环
  11. 不宜使用Selenium自动化的10个测试场景
  12. 如何使用命令行进行基本操作
  13. xu2w显示屏软件下载_LED显示屏控制软件
  14. Windows XP 系统中内置的AT命令
  15. UE4+LiveLinkFace面部动作捕捉
  16. SM6S系列TVS二级管 可通过ISO 7637-2 5a/5b测试
  17. Opencv颜色空间最全
  18. 2016年第七届java A组蓝桥杯省赛真题
  19. 11_05.【Java】线程安全与线程同步
  20. 模版之家第三方解析下载不用开年或终身会员也能下载

热门文章

  1. arcoshx怎么用计算机算,微积分常用公式及运算法则(上册).pdf.doc
  2. Vmware 15 Pro 报错 安装所需的CAB文件“Workstation.cab”已损坏,无法使用
  3. linux 命令行进入redis
  4. 浅析分布式系统背后的基础设施
  5. 【设计师必藏】国外前五SketchUp插件下载网站
  6. python3扫描周围蓝牙设备_bluescan:一个强大的蓝牙扫描器
  7. linux 交叉编译工具中没有libc和liblog库文件,NDK无法找到动态链接库;动态链接库找不到依赖的gcc库;JNI中无法找到要注册的类;and so on...
  8. android img 制作工具,图片文字制作软件下载
  9. CPU 0.2s 轻松识别十万类,超强图像识别系统 PP-ShiTu 重磅发布!
  10. python fileinputstream_fileinputstream读取网络文件