zoukankan      html  css  js  c++  java
  • 记自己在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']

    在全栈的道路上,积极向上、成熟稳重、谦虚好学、怀着炽热的心向前方的走得更远。
  • 相关阅读:
    mysql-day06
    C语言 输出二进制数
    Python学习笔记(一)
    数组指针与指针数组
    重装系统--小白版
    Java 面对对象阶段练手项目【飞机大战】
    Java环境的配置
    在Linux环境下运行C语言程序
    Torrent文件
    ubuntu下载速度慢的解决办法--修改下载源
  • 原文地址:https://www.cnblogs.com/DDgougou/p/8578618.html
Copyright © 2011-2022 走看看