前言
等了这么久,老铁来更新这篇文章啦~~
项目中有个场景需要查询一段时间内的记录,细心负责的测试小姐姐扔过来一个bug,那我们来看下这个bug!
正文
测试场景重现
前提
数据库中数据:有一条更新时间为【2019-01-01 15:10:20】的数据
查询条件
开始日期:2019-01-01 14:00:00
结束日期:2019-01-01 15:20:30
model_id: Buw2y9CQMmc1tX7HQw9MLx
scene_id: scene1
查询结果
0条记录
问题追踪
可能的原因:
时区问题(排除)
传参问题(参数不正确,排除)
返回值问题(date和string的转换,排除)
查询方式问题(靠点谱,接着看)
当时间传参方式为date或 timestamp 格式时,查询开始日期和结束日期时间差超过一天时,查询结果正常,当开始日期和结束日期时间差在一天内时,查询结果异常
传参方式为Date类型:
## Mapper.xml
<select id = "getTimes" parameterType="map" resultType="java.lang.Integer">
select
count(*) from t_model_monitor
where scene_id =#{sceneId}
and model_id= #{modelId}
<if test="start != null">
and DATE_FORMAT(update_time, '%Y-%m-%d %H:%i:%S') >= DATE_FORMAT(#{start,jdbcType=Date }, '%Y-%m-%d
%H:%i:%S')
</if>
<if test="end != null">
and DATE_FORMAT(update_time, '%Y-%m-%d %H:%i:%S') <= DATE_FORMAT(#{end,jdbcType=Date }, '%Y-%m-%d
%H:%i:%S')
</if>
and monitor =#{type}
and is_delete
= 0
</select>
传参方式为Timestamp类型:
## Mapper.xml
<select id = "getTimes" resultType="java.lang.Integer">
select
count(*)
from t_model_monitor
where scene_id =#{sceneId}
and model_id= #{modelId}
and monitor =#{type}
and is_delete= 0
<if test="end != null">
<![CDATA[ and DATE_FORMAT(update_time,'%Y-%m-%d %H:%i:%S')<= DATE_FORMAT(#{end,jdbcType = TIMESTAMP}, '%Y-%m-%d %H:%i:%S') ]]>
</if>
<if test="start != null">
<![CDATA[ and DATE_FORMAT(update_time,'%Y-%m-%d %H:%i:%S')>= DATE_FORMAT(#{start,jdbcType = TIMESTAMP}, '%Y-%m-%d %H:%i:%S') ]]>
</if>
</select>
试了一下传参方式为String
## Mapper.xml
<select id = "getTimes" resultType="java.lang.String">
select
distinct DATE_FORMAT(update_time, '%Y-%m-%d %H:%i:%S') as update_time
from t_model_monitor
where scene_id =#{sceneId}
and model_id= #{modelId}
<if test="start != null" >
and update_time >#{start}
</if>
<if test="end != null" >
and update_time < #{end}
</if>
and monitor =#{type}
and is_delete
= 0
</select>
这下查询正常了~~
结论
当查询一段时间内的数据时,如果时间精确到时分秒,建议时间传参用String类型!
Mybatis中jdbcType为Date和 TimeStamp的区别:
- jdbcType = “Date” ,返回的时间只有年月日(yyyy-MM-dd)
- jdbcType = “TimeStamp” ,返回的时间年月日和时分秒都有(yyyy-MM-dd HH:mm:ss)
总结
当查询一段时间内的数据时,如果时间精确到时分秒,建议时间传参用String类型!( 觉得还有些问题没有分析清楚,欢迎各位好友留言交流)