记自己在mybatis中设置jdbcType的一个坑
项目是用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的一个坑的更多相关文章
- JavaScript中sort方法的一个坑(leetcode 179. Largest Number)
在做 Largest Number 这道题之前,我对 sort 方法的用法是非常自信的.我很清楚不传比较因子的排序会根据元素字典序(字符串的UNICODE码位点)来排,如果要根据大小排序,需要传入一个 ...
- mybatis中设置打印sql语句application.yml
在application.yml配置文件中,找到数据源设置,添加: mybatis: configuration: log-impl:org.apache.ibatis.logging.stdout. ...
- Mybatis中的jdbcType的作用
使用MyBatis框架做更新操作时,在该字段需要更新的内容为空时,就会出现1111错误,也就是无效的列类型,这个时候你就要使用jdbcType.至于什么时候要使用到javaType我还没遇到过,而且我 ...
- MyBatis中的JdbcType映射介绍
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本 ...
- 关于 myBatis 中的 jdbcType的细节问题
前几天上线了一个 版本,第二天到公司的时候,在cat上发现了一个长sql查询非常耗时,几乎把线上的项目搞崩溃了.我马上开始排查问题.最终发现 球队的ID传过来的时候是String 类型的,但是在执行s ...
- JQuery 在循环中设置事件,最后一个覆盖了前面所有的设置
function setValidation() { for (i = 0; i < alValidations.length; i++) { //alValidations是一 ...
- 关于使用layui中的tree的一个坑
最近几天,因为项目需要,所以自学了下layui,在使用之前就对其比较感兴趣,毕竟封装的东西也不错(个人见解),在接触到layui之后,现在有个需要就是将部门做成tree的样子,开始觉得不怎么难,毕竟都 ...
- 使用scrapy中xpath选择器的一个坑点
情景如下: 一个网页下有一个ul,这个ur下有125个li标签,每个li标签下有我们想要的 url 字段(每个 url 是唯一的)和 price 字段,我们现在要访问每个li下的url并在生成的请求中 ...
- UC浏览器中Ajax请求中传递数据的一个坑
今天突然收到一个bug,有用户在其浏览器环境中一直无法提交内容,使用的是UC浏览器.当换成Chrome时,内容能够正常提交.鉴于本地没有一直使用Firefox 以及Chrome,于是去下载了一个UC ...
随机推荐
- python 守护进程、同步锁、信号量、事件、进程通信Queue
一.守护进程 1.主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes ...
- 大数据计算平台Spark内核全面解读
1.Spark介绍 Spark是起源于美国加州大学伯克利分校AMPLab的大数据计算平台,在2010年开源,目前是Apache软件基金会的顶级项目.随着Spark在大数据计算领域的暂露头角,越来越多的 ...
- 【转】具透 | 你可能不知道,iOS 10 有一个中国「特供」的联网权限功能
9 月底,苹果正式在北京成立了苹果中国研发中心.近几年,我们也在每年更新的 iOS 系统中不断看到,苹果对中国市场的关照.从早前的九宫格输入法,到最近的骚扰电话拦截,都照顾了国内用户的需求. 在 iO ...
- 钉钉自定义机器人 发送文本 换行 \n无效果
今天用php做钉钉自定义机器人 发送文本 换行 \n无效果,原来是我一直用单引号作为定义字符串,换成双引号就ok了.
- 009_npm常用命令参数总结
npm是什么 NPM的全称是Node Package Manager,是随同NodeJS一起安装的包管理和分发工具,它很方便让JavaScript开发者下载.安装.上传以及管理已经安装的包. 一.np ...
- 17 python 初学(迭代器)
生成器都是迭代器,迭代器不一定是生成器 迭代器满足两个条件: 1. 有iter方法 2. 有next方法 # list, tuple, dict, string: iterable(他们都有iter方 ...
- mysql存储引擎之MyISAM 和 InnoDB的比较
一.什么是存储引擎 存储引擎说白了就是如何存储数据.如何为存储的数据建立索引和如何更新.查询数据等技术的实现方法.因为在关系数据库中数据的存储是以表的形式存储的,所以存储引擎也可以称为表类型(即存储和 ...
- log4net配置文件
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSec ...
- Charles抓包显示乱码解决方法
[问题现象] 在抓https协议请求时,Request和Response显示乱码了: [解决办法] 第一步:点击 [工具栏-->Proxy-->SSL Proxying Settings. ...
- 算法相关——Java排序算法之希尔排序(五)
个子块,即{3,5},{1,0},{5,2},{9,4},{6,12},将每个子块进行插入排序(即第i位与第i+5位进行比较交换),初步排序结果为{3,0,2,4,6,5,1,5,9,12}.希尔排序 ...