MyBatis 数值类型 where 条件配置的坑
更多文章参考我的笔记:https://www.yuque.com/yinjianwei/vyrvkf
复现异常
我们先通过案例复现该类异常,测试项目地址:https://gitee.com/yin_jw/demo/tree/master/mybatis-demo/springboot-mybatis-demo,StudentMapper.xml 中根据条件获取学生信息的 SQL 配置如下所示。
<!-- 根据条件获取学生信息-->
<select id="listByConditions" parameterType="studentQuery" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_student
<where>
<if test="ids != null and ids.size() > 0">
AND id IN
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
<if test="name != null and name != ''">
AND name LIKE CONCAT('%', #{name}, '%')
</if>
<if test="sex != null and sex != ''">
AND sex = #{sex}
</if>
<if test="selfcardNo != null">
AND selfcard_no = #{selfcardNo}
</if>
</where>
</select>
该配置问题出在 <if test="sex != null and sex != ''"> 这段代码,sex 在传入的参数中是 Byte 类型,属于数值类型,而 sex != '' 适用于字符串类型判断,我们误将数值类型当成字符串类型配置了。
当我们错误的配置了 sex 字段的判断条件,传入 sex = 0 时,sex != '' 会返回 false,传入 sex = 1 时,sex != '' 会返回 true,同样是传入数字,为什么会出现两种不同的结果呢?
sex = 0 的执行效果如下图所示:

sex = 1 的执行效果如下图所示:

sex = 0 的执行返回内容明显不是我们需要的结果,下面我们通过源码分析来解开这个谜题。
分析源码
通过源码分析篇中的“MyBatis 源码篇-SQL 执行的流程”章节,我们知道 MyBatis 执行 SQL 最终都会交给 Executor 类执行。
前面的调试步骤省略,直接进入 CacheExecutor 类的 query 方法。

猜测 MyBatis 根据参数和映射配置文件生成 boundSql 的时候,出现了一些问题。我们一路往下 DEBUG,发现问题出在 MyBatis 对 OGNL 表达式处理上面。
org.apache.ibatis.ognl.OgnlOps#compareWithConversion(Object v1, Object v2) 该方法在比较 (Byte)0 和 "" 时,返回的是 true,也就是该方法认为两者是相同的,执行结果如下图所示。

所以,sex = 0 的条件没有出现在生成的 SQL 中。
那么当 sex = 1 的时候,compareWithConversion(Object v1, Object v2) 方法的执行结果是怎样的呢?
修改参数,调试测试接口,执行结果如下图所示:

compareWithConversion(Object v1, Object v2) 方法返回的结果是 false,其实该问题的本质是,org.apache.ibatis.ognl.OgnlOps#doubleValue(Object value) 方法当 value 是空字符串时返回 0.0D。

结论
对于数值类型的参数,在配置 where 条件的时候要注意,不能把它当成字符串类型判断,数值型只需要判断 sex != null 就可以了。
MyBatis 数值类型 where 条件配置的坑的更多相关文章
- 005 Python的数值类型
005 Python的数值类型 BIF 指的是内置函数,一般不作为变量命名.如 input,while,if,else,float,等等.整型:整数.(python3.0版本把整型和长整型结合在 ...
- myBatis 基础测试 表关联关系配置 集合 测试
myBatis 基础测试 表关联关系配置 集合 测试 测试myelipse项目源码 sql 下载 http://download.csdn.net/detail/liangrui1988/599388 ...
- mybatis sql中的条件语句
1.mybatis判断是否为空或null <if test="type!=null and type!=''"> AND type = #{type} </if& ...
- mybatis generator的generatorConfig.xml配置详解
generatorConfig.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE ge ...
- 深入浅出Mybatis系列(四)---配置详解之typeAliases别名(mybatis源码篇)
上篇文章<深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)> 介绍了properties与environments, ...
- MySQL的数值类型,时间
数值类型 整数型 tinyint smallint mediumint int|integer bigint 注意: 1, 如何选择数据类型,我们的原则是:够用就行!尽量的选择占用内存小的整型 ...
- MySQL数据类型——数值类型
1.1.1 整型 整型 占用字节 范围 范围 tinyint 1 -27~27-1 -128~127 smallint 2 -215~215-1 -32768~32767 mediumint 3 -2 ...
- MyBatis Generator自动生成的配置及使用
注意:文件名不能有中文字符,不然不能自动生成 找到MyBatis Generator.rar\MyBatis Generator\eclipse里的features和plugins文件,把这两个文件复 ...
- MySQL学习分享--数值类型
数值类型 MySQL的数值类型包括整数类型.浮点数类型.定点数类型.位类型. 整数类型 MySQL支持的整数类型有tinyint.smallint.mediumint.int.bigint(范围从小到 ...
随机推荐
- Maven -- 使用Myeclipse创建Maven项目
使用Myeclipse创建Maven项目有如下几种方式: 1.创建Maven Java项目 1.1 选择新建Maven项目 1.2.选择创建简单项目 1.3.填写项目信息 1.4.创建成功后项目目录结 ...
- Apache Flink 入门示例demo
在本文中,我们将从零开始,教您如何构建第一个Apache Flink (以下简称Flink)应用程序. 开发环境准备 Flink 可以运行在 Linux, Max OS X, 或者是 Windows ...
- FastDFS集群-安装说明
一.简介 FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适合以文件为载体的在线 ...
- 一个html,3D 标签 鼓励自己
效果如图: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w ...
- Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程
Apollo学习笔记(一):canbus模块与车辆底盘之间的CAN数据传输过程 博主现在从车载自组网信道分配和多跳路由转向了自动驾驶,没啥经验,想快些做出来个Demo还是得站在巨人的肩膀上才行,我选择 ...
- Alpha阶段--第七周Scrum Meeting
任务内容 本次会议为第六周的Scrum Meeting会议 召开时间为周日下午5点,在潮音餐厅召开,召开时间约为30分钟,对已经完成项目的总结和对今后项目设计的展望 队员 任务 张孟宇 “我的”界面代 ...
- 【EmguCV视频教程】VS2017+EmguCV3.4(C# OpenCV)高清入门视频教程
视频采用VS2017 + EmguCV3.4版本录制,内容类似本人的Python和C++版本,如果需要的朋友可加我咨询,视频共40讲,从按照到读取显示图片,图形预处理,边缘检测,形态学,角点检测,轮廓 ...
- 大公司喜欢问的Java集合类面试题
Collection Collection是基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同的元素而另一 ...
- [2018-10-29] python开发个人资源共享网--第二天
创建Django目录 startproject my_project 创建APP startapp my_app 手动创建的文件夹 log 日志 media 用户上传下载 static 静态文件 配置 ...
- LVS 十种算法
LVS虚拟服务器是章文嵩在国防科技大学就读博士期间创建的,LVS可以实现高可用的.可伸缩的网络服务. LVS集群组成: 前端:负载均衡层 (一台或多台负责调度器构成) 中间:服务器群组层 (由一组 ...