1、引入问题

近日有群成员提出一个问题:数据库是date类型,MyBatis传入timestamp类型参数,但是查询结果为 0 。如下所示:

 Preparing: select * from t_plan where begin_date = ?
Parameters: 2018-06-15 00:00:00.0(Timestamp) 
     Total: 0

可是,通过数据库管理工具可以查出数据,sql 如下所示:

select * from t_plan where begin_date = date("2018-06-15")

分析如下:

数据库的字段是date类型,前者通过mybatis传入timestamp类型参数,后者的sql语句采用的date类型。类型不同是不能进行等于比较的,2018年6月15日 不等于 2018年6月15日XX小时XX分XX秒,只能是前者包含后者关系。

2、mysql的时间类型与java的时间类型

mysql所支持的日期时间类型有:DATETIME、TIMESTAMP、DATE、TIME、YEAR,如下所示:

mysql-date-time.png

java所支持的时间类型为:java.sql.Date、java.sql.Time、java.sql.Timestamp。

3、MyBatis处理日期有两种的jdbcType

(1)jdbcType=DATE
(2)jdbcType=TIMESTAMP

备注:此时的DATE指的是java.sql.Date,不是java.util.Date,要注意两者的区别。同理,TIMESTAMP指的是java.sql.Timestamp。

4、java.util.Date 和 java.sql.Date介绍

Java中有两个Date类,一个是java.util.Date,通常情况下用它获取当前时间,另一个是java.sql.Date,是针对SQL语句使用的,它只包含日期而没有时间部分。两个类型的时间可以相互转化。

当我们使用java.util.Date作为实体的日期类型时,实际上是能够表示MySQL的三种字段类型:

(1)date
(2)datetime
(3)timestamp

5、MyBatis时间处理方式

在实际开发过程中,如果我们将java.util.Date当做参数传递给Mapper的时候,需要指定jdbctype。

(1)假如我们不指定jdbcType,那么这个日期会自动转化会MySQL的timestamp,例子如下:

 Preparing: select * from t_plan where begin_date = ?
Parameters: 2018-06-15 00:00:00.0(Timestamp) 
     Total: 0

(2)指定jdbcType=TIMESTAMP结果同上。
(3)指定jdbcType=DATE,那么MyBatis会将传入参数截取为2018-06-15,变成Date类型

6、总结

使用java.util.Date作为参数传递给Mapper时,不管MySQL的日期字段类型是date、datetime或者timestamp中的哪一种,默认缺省情况下,MyBatis都能够自动做出类型转换,可以直接使用 =、>、<、>=、<=符号来进行筛选。

但是,当我们手动指定jdbcType=DATE的时候,MyBatis会自动截取掉时间,只保留日期。如果MySQL的日期字段类型是datetime或者timestamp一定不要这么写,否则属于画蛇添足,自讨没趣。

标签: none

添加新评论