记自己在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 ...
随机推荐
- 《Java大学教程》—第18章 高级图形编程
自测题:1. 在图形应用程序中为用户提供选择的多种方式:P433下拉菜单(pull-down menu).弹出式菜单(pop-up menu).对话框窗口(dialogue window).单选 ...
- Iframe框架+table布局 +div布局实例
<td colspan="2" style="width: 80%"> <iframe src="http://www.baidu. ...
- hover效果的几种方式
1.改变透明度 #share_wrap a{display: inline-block;width: 48px;height: 44px;background: url(/images/finance ...
- php文件管理,能够点击依照时间,大小,名称排序
php文件管理.能够点击依照时间.大小,名称排序 本例没实用到jquery 演示 PHP Code <?php $rootdir="./"; $spacen ...
- linux下安装jdk_mysql_tomcat_redis
目前搬我以前的笔记,每个人做笔记方式都不一样,看别人的风格,生成自己的风格 1.linux安装软件和redis学习 jdk --- java开发运行环境 Tomcat - WEB程序的服务器 Mysq ...
- 【转】如何使用分区助手完美迁移系统到SSD固态硬盘?
自从SSD固态硬盘出世以来,一直都被持续关注着,SSD的性能优势让无数用户起了将操作系统迁移到SSD的心思,直接后果就是让无数机械硬盘为止黯然退场,很多软件都可以做到系统迁移,然而,被完美迁移的系统却 ...
- tar只解压tar包中某个文件
如果tar包很大,而只想解压出其中某个文件.方法如下: 只想解压出Redis-1.972.tar 中的Changes文件,来查看有哪些更改. [root@uplooking]# tar -tf Re ...
- i春秋-百度杯十月场-EXEC
进入网站,查看源代码,发现是用vim编辑,而抓包没有有效信息,加参数也无果.百度查了一下vim能形成什么文件.找到答案说,用vim编辑文本xxx.php中途退出,会自动创建一个文件.xxx.php.s ...
- 线程概念( 线程的特点,进程与线程的关系, 线程和python理论知识,线程的创建)
参考博客: https://www.cnblogs.com/xiao987334176/p/9041318.html 线程概念的引入背景 进程 之前我们已经了解了操作系统中进程的概念,程序并不能单独运 ...
- Java虚拟机垃圾收集器
一.判断对象存活的算法 1.引用计数(Reference Counting)算法 给对象添加一个引用计数器,每当有一个地方引用时,计数器加1.当引用失效时,计数器减1.当计数器的值为0的时候说该对象不 ...