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

service层:

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

  dao层:

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

  dao层的xml文件:

 <!--measureStartTime为测量时间,在java中是一个java.util.Date,在mysql中是TIMESTAMP类型-->
<resultMap id="healthDataMap" type="map">
<result property="appuserId" column="appuserId" javaType="java.lang.String" jdbcType="CHAR"/>
<result property="measureStartTime" column="measureStartTime" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
<result property="measureSecondLength" column="measureSecondLength" javaType="java.lang.Integer" jdbcType="INTEGER"/>
<result property="hrOverallAvg" column="hrOverallAvg" javaType="java.lang.String" jdbcType="VARCHAR"/>
<result property="chiefComplaint_symptom" column="chiefComplaint_symptom" javaType="java.lang.String" jdbcType="VARCHAR"/>
<result property="chiefComplaint_diet" column="chiefComplaint_diet" javaType="java.lang.String" jdbcType="VARCHAR"/>
<result property="chiefComplaint_activity" column="chiefComplaint_activity" javaType="java.lang.String" jdbcType="VARCHAR"/>
</resultMap> <select id="getHealthDataList" parameterType="map" resultMap="healthDataMap">
select
ea.appuserId,ea.measureStartTime,ed.measureSecondLength,ea.hrOverallAvg,ea.chiefComplaint_symptom,
ea.chiefComplaint_diet,ea.chiefComplaint_activity
from
ecg_auto_analysis ea
left join
ecg_data ed
on
ed.autoAnalysisId = ea.id
<where>
<if test="appuserId != null and appuserId != ''">
and ea.appuserId = #{appuserId,jdbcType=CHAR}
</if>
<if test="startDate != null and startDate != ''">
and ea.measureStartTime > #{startDate,jdbcType=Date}
</if>
<if test="endDate != null and endDate != ''">
and #{endDate,jdbcType=Date} > ea.measureStartTime
</if>
</where>
</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号):

 select
ea.appuserId,ea.measureStartTime,ed.measureSecondLength,ea.hrOverallAvg,ea.chiefComplaint_symptom,ea.chiefComplaint_diet,ea.chiefComplaint_activity
from
ecg_auto_analysis ea
left join
ecg_data ed
on
ed.autoAnalysisId = ea.id
where
ea.appuserId = "393967382ec34f53a53a4d49271a422a"
and ea.measureStartTime > "2018-03-09 00:00:00"
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']

记自己在mybatis中设置jdbcType的一个坑的更多相关文章

  1. JavaScript中sort方法的一个坑(leetcode 179. Largest Number)

    在做 Largest Number 这道题之前,我对 sort 方法的用法是非常自信的.我很清楚不传比较因子的排序会根据元素字典序(字符串的UNICODE码位点)来排,如果要根据大小排序,需要传入一个 ...

  2. mybatis中设置打印sql语句application.yml

    在application.yml配置文件中,找到数据源设置,添加: mybatis: configuration: log-impl:org.apache.ibatis.logging.stdout. ...

  3. Mybatis中的jdbcType的作用

    使用MyBatis框架做更新操作时,在该字段需要更新的内容为空时,就会出现1111错误,也就是无效的列类型,这个时候你就要使用jdbcType.至于什么时候要使用到javaType我还没遇到过,而且我 ...

  4. MyBatis中的JdbcType映射介绍

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.                                               本 ...

  5. 关于 myBatis 中的 jdbcType的细节问题

    前几天上线了一个 版本,第二天到公司的时候,在cat上发现了一个长sql查询非常耗时,几乎把线上的项目搞崩溃了.我马上开始排查问题.最终发现 球队的ID传过来的时候是String 类型的,但是在执行s ...

  6. JQuery 在循环中设置事件,最后一个覆盖了前面所有的设置

    function setValidation() {         for (i = 0; i < alValidations.length; i++) { //alValidations是一 ...

  7. 关于使用layui中的tree的一个坑

    最近几天,因为项目需要,所以自学了下layui,在使用之前就对其比较感兴趣,毕竟封装的东西也不错(个人见解),在接触到layui之后,现在有个需要就是将部门做成tree的样子,开始觉得不怎么难,毕竟都 ...

  8. 使用scrapy中xpath选择器的一个坑点

    情景如下: 一个网页下有一个ul,这个ur下有125个li标签,每个li标签下有我们想要的 url 字段(每个 url 是唯一的)和 price 字段,我们现在要访问每个li下的url并在生成的请求中 ...

  9. UC浏览器中Ajax请求中传递数据的一个坑

    今天突然收到一个bug,有用户在其浏览器环境中一直无法提交内容,使用的是UC浏览器.当换成Chrome时,内容能够正常提交.鉴于本地没有一直使用Firefox 以及Chrome,于是去下载了一个UC ...

随机推荐

  1. Fluentd初探 简介与安装

    Fluentd是一个开源的数据收集器,专为处理数据流设计,有点像 syslogd ,但是使用JSON作为数据格式.它采用了插件式的架构,具有高可扩展性高可用性,同时还实现了高可靠的信息转发. 据分(Y ...

  2. C#深度学习の委托深度解析

    一.我们在使用C#的过程中,不可避免的用到了委托. 委托的本质是什么呢? 从语法上看,委托是对方法的抽象封装,例如:public void print1(),public void print2(), ...

  3. LDAP安装配置(windows)

    目录 概述 测试环境 安装过程 配置启动 客户端介绍 多级DC的ldif文件的配置 [一].概述 什么叫LDAP呢,概念的东西这里就不多讲了,网上搜索下有很多,本文的重点是介绍如何在windows平台 ...

  4. SQLite 知识摘要 --- 线程模式、事务模式

    本篇主要从SQLite事务执行的原理中寻找如何更高效地使用它. 本篇预备知识 我们先来了解下SQLite执行事务的基本流程,状态变化过程,再分析怎么使用才更优.SQLite定义的锁的状态有如下几种: ...

  5. 小a与黄金街道 (欧拉函数)

    题意:a, b两个人在长度为n的一维数轴上(从1开始).a在1,b在n.每个人以1m/s的速度相向而行,则每一时刻存在坐标x,y,当cgd(n, x)==1,gcd(n, y)==1时,t1=k^x, ...

  6. springboot中使用freemarker生成word文档并打包成zip下载(简历)

    一.设计出的简历模板图以及给的简历小图标切图         二.按照简历模板图新建简历word文件 :${字段名},同时将图片插入到word中,并将建好的word文件另存为xml文件:    三.直 ...

  7. jenkins使用4----git maven工具连接

    搭建完git服务器 将jenkins服务器的的公钥传到git服务器的/home/git/.ssh的authorized_keys文件下 ssh端口2994 创建工程 配置完maven发现创建项目没有m ...

  8. 记一次Dubbo服务注册异常

            公司项目重构,把dubbo版本从2.5.8升级为2.6.2.升级后在本地运行一点问题都没有:可是通过公司自研的发布系统将项目发布到测试环境的linux服务器下面后,出现了dubbo服务 ...

  9. eclipse不能运行Struts2项目

    刚接触Struts2项目,本想写个HelloWorld上手,谁知道光eclipse配置tomcat就鼓捣一晚上,查阅各种资料. 项目刚开始报错: "java.lang.ClassNotFou ...

  10. 容器技术|Docker三剑客之docker-compose

    三剑客简介 docker-machine docker技术是基于Linux内核的cgroup技术实现的,那么问题来了,在非Linux平台上是否就不能使用docker技术了呢?答案是可以的,不过显然需要 ...