MyBatis处理MySQL日期类型
1.1 简述
在日常的开发中,难免会遇到时间的比较或者区间等问题,该博文主要是正对Mybatis与MySQL数据库相结合的日期类型讲解。
1.2 类型
下面给大家列举了三种表示时间的类型:
1.2.1 DATETIME
显示格式:yyyy-MM-dd HH:mm:ss 时间范围:[ 1000-01-01 00:00:00到9999-12-31 23:59:59]
1.2.2 DATE
显示格式:yyyy-MM-dd HH:mm:ss 时间范围:[1000-01-01到9999-12-31]
1.2.3 TIMESTAMP
显示格式:yyyy-MM-dd HH:mm:ss 时间范围:[ 1970-01-01 00:00:00到2037-12-31 23:59:59]
1.3 MyBatis处理日期有两种的jdbcType
1、jdbcType=DATE 2、jdbcType=TIMESTAMP
二、当我们使用java.util.Date作为实体的日期类型时(JAVA没有DateTime这个类,Date类能够同时表示日期和时间),java.util.Date实际上是能够表示MySQL的三种字段类型: 1、date 2、datetime 3、timestamp
1.4 MyBatis处理方式
而实际将java.util.Date当做参数传递给Mapper的时候
1、假如我们不指定jdbcType,那么这个日期会自动转化会MySQL的timestamp,例子如下:
18:13:54.723 [main] DEBUG c.x.d.B.countFirstOverdueSmsReport - ==> Preparing: select count(*) from bill_flow where (pay_status = NOT_PAID and bill_date = ? ) or (pay_status = PAID and bill_date = ? and finish_time BETWEEN ? and ?) 18:13:54.797 [main] DEBUG c.x.d.B.countFirstOverdueSmsReport - ==> Parameters: 2018-07-24 00:00:00.0(Timestamp), 2018-07-24 00:00:00.0(Timestamp), 2018-07-25 00:00:00.0(Timestamp), 2018-07-25 23:59:59.0(Timestamp) 18:13:54.917 [main] DEBUG c.x.d.B.countFirstOverdueSmsReport - <== Total: 1
2、指定jdbcType=TIMESTAMP结果同上。 3、指定jdbcType=DATE,那么MyBatis会将传入参数截取为2018-07-24(Date)
1.5 示例
最近写代码时需要写时间比较(查询时间介于当前时间和当前时间加一天,记录一下。
java代码:
Map<String,Object> param = new HashMap<>(); long cur=System.currentTimeMillis(); long dayh=24*60*60*1000; //一天的毫秒数 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String startTime = sdf.format(new Date(cur)); //当前时间加一天 String endTime = sdf.format(new Date(cur+dayh)); param.put("startDate",startTime); param.put("endDate",endTime);`
sql语句:
select * from db <trim prefix="where" prefixOverrides="and | or"> <if test="startDate != null and endDate != null"> and startTime between #{startDate} and #{endDate} </if> </trim>
1.6 MySQL中日期比较大小
假如有个表product有个字段add_time,它的数据类型为datetime,有人可能会这样写sql:
select * from product where add_time = 2013-01-12
对于这种语句,如果你存储的格式是yyyy-MM-dd是这样的,那么OK。如果你存储的格式是:yyyy-MM-dd HH:mm:ss这种格式就悲剧了,这时你就可以使用DATE()函数用来返回日期的部分,所以这条sql应该如下处理:
select * from product where Date(add_time) = 2013-01-12
再来一个,如果你要查询2013年1月份加入的产品呢?
select * from product where date(add_time) between 2013-01-01 and 2013-01-31 --你还可以这样写: select * from product where Year(add_time) = 2013 and Month(add_time) = 1
1.7 总结
使用jav a.util.Date作为参数传递给Mapper时,不管MySQL的日期字段类型是date、datetime或者timestamp中的哪一种,MyBatis都能够自动做出类型转换,可以直接使用 =、>、<、>=、<=符号来进行筛选。
唯一的不同点是指定jdbcType=DATE的时候,MyBatis会自动截取掉时间,如果MySQL的日期字段类型是datetime或者timestamp一定不要这么写。
总之不手动指定参数的jdbcType必然没有问题。