Mybatis+0+null,小问题引发的血案
Mybatis在进行<if test="status != null and status != ''">
判空操作时,假设status为0的时候,该推断条件的值为false,也就是说Mybatis此时把0作为null来进行推断的,所以遇到这样的情况时。仅仅能依照以下这种方法来办!
一、源代码调查结果
遇到这个问题时。我翻看了Mybatis的源代码,发现其在ExpressionEvaluator.java类的evaluateBoolean方法处返回了false,这个源代码包的分析方式和源代码分析 There is no getter for property named ‘*’ in ‘class java.lang.String有极大的同样之处。
但发现了问题。也然并卵,改动Mybatis的源代码我是不行,所以仅仅能曲线救国!
二、场景分析
数据库字段
`status` tinyint(2) NOT NULL COMMENT '0未支付,1已支付',
此时0表示未支付,1表示支付。那么依照一般的逻辑来看。查询语句须要写成这样的形式:
select * from ym_deals y WHERE d.deal_id = 1
<if test="status != null and status != ''">
and y.status = #{status}
</if>
其意义在于。当查询參数不传递未支付或者支付条件时。就须要查询status为0和1的所有结果。也就是说没有条件and y.status = #{status}
。但事实就纠结了,当status传递的參数为1时,if条件的结果为true,也就是说sql语句变成了select * from ym_deals y WHERE d.deal_id = 1 and y.status=1
,查询结果正常,但假设status为0此时,sql语句变成了select * from ym_deals y WHERE d.deal_id = 1
,与预期结果select * from ym_deals y WHERE d.deal_id = 1 and y.status=0
显然是不符的!
也就是说,Mybatis自作主张的把status为0的条件当做了if的false结果!
三、解决的方法
①、对传递參数拦截
public static int parseStringToInt(Object parameter, int defualtValue) {
try {
if ((parameter == null) || (parameter.equals(""))) {
return defualtValue;
}
return Integer.parseInt(parameter.toString());
} catch (Exception ex) {
}
return 0;
}
vo.addParams("status", StrUtil.parseStringToInt(vo.getParams("status"), -1));
也就是说在查询所有支付状态的订单时,把status的值转换为-1.
②、重构Mybatis的查询语句
select * from ym_deals y WHERE d.deal_id = 1
<if test="status != -1">
and y.status = #{status}
</if>
此时不再判空,而判-1。
依照以上的办法就攻克了问题。不知道你那是否有更好的解决的方法?
四、后记
这篇文章发表之后,有热心的朋友给出以下的解决的方法:
lengjian68 status是Integer 类型的 把status!=‘’ 给去掉
去掉就好了1楼 qq_30159115 确定是 int类型的就不用 推断 status != ‘’ 就搞定了
Re: Optimistic_ 发表 回复qq_30159115:给力啊。感谢!
推断不是为空。对于int类型就是在推断不为0么?
依照朋友给出的观点。我尝试了一下,结果如朋友所说。status确定为integer类型的,把status!=”给去掉就好了。
那么如今又一次来看,我本来的做法就有问题,integer类型的,我干嘛要用status!=”来进行推断,这显然是一种不负责任的做法,至于<if test="status != null and status != ''">
的推断条件。显然是错误的,从原则上来讲,该推断条件仅仅能来推断status为string类型的,用来推断integer类型。岂不贻笑慷慨,至于后面我提出的解决方式,显然也就无力苍白。我仅仅想把这篇文章立刻删掉,好不再误导他人。
但看到
Re: Optimistic_ 发表 回复qq_30159115:给力啊!感谢!
推断不是为空,对于int类型就是在推断不为0么?
以下这位朋友的疑问,我认为,这篇文章存在另一些价值,由于还有和我一样的朋友在犯错。“推断不是为空,对于int类型就是在推断不为0么?”这样的认识显然是第二种错误,integer类型非常明显存在为null的情况,那么对于int类型当然不是在推断为0的。(当然了。这位仁兄说int类型,在严格意义上讲。就不存在null的可能了,那么我仅仅能武断的猜測任务。这位朋友是在说integer,请原谅我的鲁莽)
那么得出下面结论:
<if test="status != null">
中status为integer类型的。status=0的推断结果为true。<if test="status != null and status != ''">
中status为integer类型的,status=0的推断结果为false。mybatis把status作为了string来进行推断。- 假设status为integer,提前对status进行去空操作,再推断
<if test="status != -1">
在有的时候也是一种曲线救国。
相关文章
感谢您阅读【沉默王二的博客】,假设王二的博客给您带来一丝帮助或感动。我(也就是王二)将不甚荣幸。
假设您碰巧喜欢。能够留言或者私信我,这将是我鼓捣很多其它优秀文章的最强动力。
Mybatis+0+null,小问题引发的血案的更多相关文章
- elasticsearch5.0.1集群一次误删除kibana索引引发的血案
elasticsearch集群中一次删除kibana索引引发的血案 1.问题发生的过程: 早上的时候有某个索引无法看到报表数据,于是就点该报表多次,估计集群被点挂了,报错:Elasticsearch ...
- 一个无锁消息队列引发的血案(六)——RingQueue(中) 休眠的艺术 [续]
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
- 一个无锁消息队列引发的血案(五)——RingQueue(中) 休眠的艺术
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
- 一个无锁消息队列引发的血案(三)——地:q3.h 与 RingBuffer
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
- Integer.parseInt 引发的血案
Integer.parseInt 处理一个空字符串, 结果出错了, 程序没有注意到,搞了很久, 引发了血案啊!! 最后,终于 观察到了, 最后的部分: Caused by: java.lang.NoC ...
- Replication的犄角旮旯(六)-- 一个DDL引发的血案(上)(如何近似估算DDL操作进度)
<Replication的犄角旮旯>系列导读 Replication的犄角旮旯(一)--变更订阅端表名的应用场景 Replication的犄角旮旯(二)--寻找订阅端丢失的记录 Repli ...
- 转:一个Sqrt函数引发的血案
转自:http://www.cnblogs.com/pkuoliver/archive/2010/10/06/1844725.html 源码下载地址:http://diducoder.com/sotr ...
- 一个Sqrt函数引发的血案(转)
作者: 码农1946 来源: 博客园 发布时间: 2013-10-09 11:37 阅读: 4556 次 推荐: 41 原文链接 [收藏] 好吧,我承认我标题党了,不过既然你来了, ...
- 一个无锁消息队列引发的血案(四)——月:RingQueue(上) 自旋锁
目录 (一)起因 (二)混合自旋锁 (三)q3.h 与 RingBuffer (四)RingQueue(上) 自旋锁 (五)RingQueue(中) 休眠的艺术 (六)RingQueue(中) 休眠的 ...
随机推荐
- 面向对象之继承-5种JavaScript继承的方法
今天我们讨论一下常用的几种继承方法:首先我们创建一个动物函数Animal: function Animal () { this.species = '动物' }再写准备名叫猫咪的函数Cat: func ...
- python 画图
1.根据实际图形,用符号画出原来图形 from PIL import Image import argparse #命令行输入参数处理 parser = argparse.ArgumentParser ...
- 【Codeforces827D/CF827D】Best Edge Weight(最小生成树性质+倍增/树链剖分+线段树)
题目 Codeforces827D 分析 倍增神题--(感谢T*C神犇给我讲qwq) 这道题需要考虑最小生成树的性质.首先随便求出一棵最小生成树,把树边和非树边分开处理. 首先,对于非树边\((u,v ...
- 点击文字弹出一个DIV层窗口代码 【或FORM表单 并且获取点击按钮的ID值】
点击不同按钮咨询不同的 专家 <?php for($i=1;$i<5;$i++){ $uid=$i; //用户ID ?> <a class="a_click" ...
- 小小的IP,大大的耦合,你痛过吗?
什么是耦合? 耦合,是架构中,本来不相干的代码.模块.服务.系统因为某些原因联系在一起,各自独立性差,影响则相互影响,变动则相互变动的一种架构状态. 感官上,怎么发现系统中的耦合? 作为技术人,每每在 ...
- fcc html5 css 练习1
font-size: 字号 利用link导入新字体再引用<link href="https://fonts.gdgdocs.org/css?family=Lobster" ...
- hibernate 级联删除报更新失败的问题(org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update)
首先hibernate级联删除的前提是,首先需要在映射文件中配置,配置多表之间的关联关系: 下面以部门表(Dept)和员工表(Emp)为例: 1.在Emp.hbm.xml映射文件中配置many-to- ...
- Core 项目下使用SQl语句
public static DataTable ExeQuery(string connectionString, CommandType cmdType, string cmdText) { usi ...
- CloseableHttpClient 在使用过程中遇到的问题
代码是前辈写的,在对代码进行压测的时候遇到了个问题,最大线程是 不能超过setDefaultMaxPerRoute设置的数字,一点超过 就会死掉.这里会报错 connection pool shut ...
- 网际协议IP简述
最近花了些时间重新回顾了谢希仁教授主编的<计算机网络>关于网络层的章节,这是一本高校教材,里面关于计算机网络的内容比较基础,并且讲的很细致,笔者针对网际协议IP地址部分觉得有必要进行阅读后 ...