记自己在mybatis中设置jdbcType的一个坑

  

  项目是用ssm搭建的。主要是为app数据接口。其中有一个需求就app想要查询一段时间内某个用户的测量信息,所以app给我后端传递了3个参数,分别是appuserId(String),startDate(Date),endDate(Date)。我在controller中验证参数没问题之后我将参数传递给service层,然后在service层传递给dao层,执行真正的sql语句查询。

 

service层:

1 Map<String, Object> conditionMap = new HashMap<>(3);
2 conditionMap.put("appuserId", appuserId);
3 conditionMap.put("startDate", startDate);
4 conditionMap.put("endDate", endDate);
5 
6 List<Map<String, Object>> list1 = ecgAutoAnalysisMapper.getHealthDataList(conditionMap);

  dao层:

  1 List<Map<String, Object>> getHealthDataList(Map<String, Object> conditionMap); 

   dao层的xml文件:

 1 <!--measureStartTime为测量时间,在java中是一个java.util.Date,在mysql中是TIMESTAMP类型-->
 2 <resultMap id="healthDataMap" type="map">
 3   <result property="appuserId" column="appuserId" javaType="java.lang.String" jdbcType="CHAR"/>
 4   <result property="measureStartTime" column="measureStartTime" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
 5   <result property="measureSecondLength" column="measureSecondLength" javaType="java.lang.Integer" jdbcType="INTEGER"/>
 6   <result property="hrOverallAvg" column="hrOverallAvg" javaType="java.lang.String" jdbcType="VARCHAR"/>
 7   <result property="chiefComplaint_symptom" column="chiefComplaint_symptom" javaType="java.lang.String" jdbcType="VARCHAR"/>
 8   <result property="chiefComplaint_diet" column="chiefComplaint_diet" javaType="java.lang.String" jdbcType="VARCHAR"/>
 9   <result property="chiefComplaint_activity" column="chiefComplaint_activity" javaType="java.lang.String" jdbcType="VARCHAR"/>
10 </resultMap>
11 
12 <select id="getHealthDataList" parameterType="map" resultMap="healthDataMap">
13   select
14       ea.appuserId,ea.measureStartTime,ed.measureSecondLength,ea.hrOverallAvg,ea.chiefComplaint_symptom,
15       ea.chiefComplaint_diet,ea.chiefComplaint_activity
16   from
17       ecg_auto_analysis ea
18   left join
19       ecg_data ed
20   on
21       ed.autoAnalysisId = ea.id
22   <where>
23     <if test="appuserId != null and appuserId != ''">
24       and ea.appuserId = #{appuserId,jdbcType=CHAR}
25     </if>
26     <if test="startDate != null and startDate != ''">
27       and ea.measureStartTime > #{startDate,jdbcType=Date}
28     </if>
29     <if test="endDate != null and endDate != ''">
30       and #{endDate,jdbcType=Date} > ea.measureStartTime
31     </if>
32   </where>
33 </select>

 

  结果是查询出来的的结果与实际的不一样。比如app传递参数,appuserId是“393967382ec34f53a53a4d49271a422a”,startDate是“2018-03-09 00:00:00”,endDate是“2018-03-15 23:59:59”,在数据库中这个用户在这段时间的测量记录有7条,而在mybatis中查询出来的只有4条。很明显是mybatis的sql语句写错了。

数据库查询语句及结果(可以看到测量时间集中在两天,一个是3月9号,一个是3月15号):

 1 select
 2     ea.appuserId,ea.measureStartTime,ed.measureSecondLength,ea.hrOverallAvg,ea.chiefComplaint_symptom,ea.chiefComplaint_diet,ea.chiefComplaint_activity
 3 from
 4     ecg_auto_analysis ea
 5 left join
 6     ecg_data ed
 7 on
 8     ed.autoAnalysisId = ea.id
 9 where
10     ea.appuserId = "393967382ec34f53a53a4d49271a422a"
11     and ea.measureStartTime > "2018-03-09 00:00:00"
12     and "2018-03-15 23:59:59" > ea.measureStartTime

 

  我是这样解决的,当然故事很曲折,也很折磨人:

  1)先注释掉最后的两个if语句,mybatis的查询结果为7,证明问题就出在最后两个if语句中;

  2)通过翻阅以前的代码,我把这两个if语句中的 jdbcType=Date 去掉,查询结果为7,然后加上  jdbcType=Date 查询结果又为4。没错,问题就出在这句话上,为啥不加就好了,加上就不对了;

  3)网上查询资料,对jdbcType这个参数的描述不多,作用不清楚,大概的意思是“jdbcType这个参数的应用场景就是,当执行mapping文件的时候,有个映射的参数为空,那么无法确定他的类型,这个时候就需要jdbcType来确定类型“。可我还是不清除啥原因导致我的查询结果不正确;

  4)最后看了好长时间,我把 jdbcType=Date 改为 jdbcType=TIMESTAMP,查询结果正确了(这一步花了太多时间)。

 

  我猜想原因是这样的,当我不设置jdbcType时,最后两个if语句在执行比较时,会把参数转换为正确的日期类型,就是 “年月日+时分秒”这种。当我设置 jdbcType=Date 时,就指定日期只用”年月日,所以传递进来的startDate与endDate就变为“2018-03-09 ”,“2018-03-15”,那在此时间段的记录当然只有4条了。但是设置 jdbcType=TIMESTAMP 时,传递进来啥就是啥,所以符合记录的只有7条了,原因就是这样。最后看看mysql数据库中datetime、date、timestamp三种数据类型的区别吧:

 


    1) DATETIME

显示格式:YYYY-MM-DD HH:MM:SS
时间范围:[ '1000-01-01 00:00:00'到'9999-12-31 23:59:59']

2) DATE

显示格式:YYYY-MM-DD
时间范围:['1000-01-01'到'9999-12-31']

3) TIMESTAMP

显示格式:YYYY-MM-DD HH:MM:SS
时间范围:[ '1970-01-01 00:00:00'到'2037-12-31 23:59:59']

 

posted @ 2018-03-16 09:44  Erneste  阅读(21008)  评论(0编辑  收藏  举报