MyBatis的坑(动态SQL会把0和空串比较相等为true)
文章目录
- 前言
- 一、场景如下
- 二、原因分析
- 1. 源码分析
- 2. 写代码验证
- 三、解决办法
- 代码及执行结果如下
- 总结
前言
在开发过程中遇到MyBatis的动态SQL的if条件不生效的情况,但经过debuger发现并不是参数问题,已经拿到了参数并传给了MyBatis,且从表达式来看是为true的,那么为什么不生效呢?
一、场景如下
- mapper.xml代码:
- 模拟Service代码
按照传入的条件subsidySum为0,那么对于<if test="subsidySum != '' and subsidySum != null">
来说应该是为true才对,那么执行完整的SQL应该为:
select long_subsidy_his_id, subsidy_name, subsidy_sum
from long_term_subsidy_his
where 1 = 1and subsidy_name like CONCAT("%", ?, "%")
- 执行结果
我们发现动态SQL并没有如期为true把条件拼上,那么是为什么呢
<if test="subsidySum != '' and subsidySum != null">AND subsidy_sum like CONCAT("%",#{subsidySum},"%")
</if>
二、原因分析
现在问题很明显就是表达式if test="subsidySum != '' and subsidySum != null"
为false了,那么是为什么呢?
首先我先将subsidySum != ''
这个条件去掉,结果意外发现表达式竟然成立为true了,那么很明显问题就是出现在这个空串比较了,接着我们去看源码。
1. 源码分析
前面找源码过程省略,直接跳到关键地方
MyBatis 会将if标签的test属性使用ExpressionEvaluator测试一下是否为true或者为false:
public class ExpressionEvaluator {public boolean evaluateBoolean(String expression, Object parameterObject) {Object value = OgnlCache.getValue(expression, parameterObject);if (value instanceof Boolean) {return (Boolean) value;}if (value instanceof Number) {return new BigDecimal(String.valueOf(value)).compareTo(BigDecimal.ZERO) != 0;}return value != null;}/*** @deprecated Since 3.5.9, use the {@link #evaluateIterable(String, Object, boolean)}.*/@Deprecatedpublic Iterable<?> evaluateIterable(String expression, Object parameterObject) {return evaluateIterable(expression, parameterObject, false);}/*** @since 3.5.9*/public Iterable<?> evaluateIterable(String expression, Object parameterObject, boolean nullable) {Object value = OgnlCache.getValue(expression, parameterObject);if (value == null) {if (nullable) {return null;} else {throw new BuilderException("The expression '" + expression + "' evaluated to a null value.");}}if (value instanceof Iterable) {return (Iterable<?>) value;}if (value.getClass().isArray()) {// the array may be primitive, so Arrays.asList() may throw// a ClassCastException (issue 209). Do the work manually// Curse primitives! :) (JGB)int size = Array.getLength(value);List<Object> answer = new ArrayList<>();for (int i = 0; i < size; i++) {Object o = Array.get(value, i);answer.add(o);}return answer;}if (value instanceof Map) {return ((Map) value).entrySet();}throw new BuilderException("Error evaluating expression '" + expression + "'. Return value (" + value + ") was not iterable.");}}
从源码看出,MyBatis使用的Ognl表达式来获取test属性的值
2. 写代码验证
结果发现真的为false
所以原因就是Ognl表达式会把0和空字符串比较为相等
三、解决办法
将空串比较条件去掉,也就是将subsidySum != ''
这个条件去掉
代码及执行结果如下
总结
- 本文简单讲述了MyBatis动态SQL的if条件不生效的情况,以及为什么MyBatis动态SQL会把0和空串比较为相等true的原因,这算是MyBatis的一个坑了。
- 欢迎大家提出建议以及批评,有任何问题可以私信。
相关文章:

MyBatis的坑(动态SQL会把0和空串比较相等为true)
文章目录 前言一、场景如下二、原因分析1. 源码分析2. 写代码验证 三、解决办法代码及执行结果如下 总结 前言 在开发过程中遇到MyBatis的动态SQL的if条件不生效的情况,但经过debuger发现并不是参数问题,已经拿到了参数并传给了MyBatis,且从表…...

Springboot事务控制中A方法调用B方法@Transactional生效与不生效情况实战总结
介绍 本篇对Springboot事务控制中A方法调用B方法Transactional生效与不生效情况进行实战总结,让容易忘记或者困扰初学者甚至老鸟的开发者,只需要看这一篇文章即可立马找到解决方案,这就是干货的价值。喜欢的朋友别忘记来个一键三连哈&#x…...
python -【三】循环语句
一、while 循环 while 语法 while 条件: 条件满足时,做事情 a 0 while a < 100:print(i like python ...)a 1求 1-100 的总和 i 1 sum 0 while i < 100:sum ii 1 print(f1-100 的和是 {sum})""" 1-100 的和是 5050 ""&…...

类的内存对齐位段位图布隆过滤器哈希切割一致性哈希
文章目录 一、类的内存对齐1.1规则1.2原因 二、位段2.1介绍2.2内存分配问题2.3跨平台问题2.4使用的注意事项 三、位图的应用3.1 给40亿个不重复的无符号整数,找给定的一个数。(int的范围可以到达42亿多)3.2 给定100亿个整数,设计算…...

于ThinkPHP开发的赛事报名小程序
基于ThinkPHP开发的赛事报名微信小程序 功能包括 1、参赛公告 2、会员中心(会员注册、登录、成绩查询、资料管理、参赛记录管理) 3、个人报名和企业报名 (身份证验证防止重复报名) 4、培训报名 5、查询是否在库人员,根…...

前端学习--React部分
文章目录 前端学习--React部分前言1.React简介1.1React的特点1.2引入文件1.3JSX🍉JSX简介与使用🍉JSX语法规则 1.4模块与组件🍉模块🍉组件 1.5安装开发者工具 2.React面向组件编程2.1创建组件🍉函数式组件🍉…...

24V_2A_1.2MHZ|PCD0303升压恒频LCD背光源专用电路超小体积封装
概述 PCD0303是一个恒定频率,6针SOT23电流模式升压转换器用于小型低功耗应用。PCD0303 以1.2MHz切换,并且允许使用微小的,低成本电容器和电感器2mm或更小,内部软启动会产生较小的涌入电流延长电池寿命。PCD0303具有自动切换至轻负载下的脉冲…...
python生成词云图
生成词云图的话需要先对数据进行分词处理 , 分词方法点击查看 import pandas as pd from collections import Counter from wordcloud import WordCloud import matplotlib.pyplot as plt# 假设您已经按照之前的步骤处理了数据,并且处理后的数据保存在comments_proc…...

【使用ChatGPT构建应用程序】应用程序开发概述:1. 管理秘钥、2. 数据安全、3. 与应用程序解耦、4. 注意提示语的注入攻击
文章目录 一. 首先注意的两个方面1. 管理API密钥1.1. 用户提供API密钥1.2. 你自己提供API密钥 2. 数据安全和数据隐私 二. 软件架构设计原则:与应用程序解耦三. 注意LLM提示语的注入攻击1. 分析输入和输出2. 监控和审计3. 其他要注意的注入情况 在了解了ChatGPT的文…...
【JavaScript脚本宇宙】不可或缺的Web开发工具:图表和可视化
图形化你的数据:六款顶级JavaScript库全接触 前言 在本文中,我们将深入探讨六个强大的JavaScript库,这些库被广泛应用于数据可视化和交互式图形展示。我们将了解每个库的概述、主要特性、使用示例以及使用场景,以帮助读者更全面…...
自然语言处理(NLP)中的迁移学习
Transfer Learning in NLP 迁移学习(Transfer Learning)无疑是目前深度学习中的新热点(相对而言)。在计算机视觉领域,它已经应用了一段时间,人们使用经过训练的模型从庞大的ImageNet数据集中学习特征&…...

PLC集成BL121PO网关优化智能电网的远程管理PLC转OPC UA协议
随着工业自动化技术的不断发展,智能电网等复杂系统对于设备之间高效通信的需求日益增加。PLC转OPC UA协议转换网关BL121PO作为一款领先的协议转换设备,通过其独特的设计和功能,为用户提供了高效、安全的PLC接入OPC UA的解决方案。 设备概述 …...

爬虫案例(读书网)
一.我们还是使用简单的bs4库和lxml,使用xpath: 导入下面的库: import requests from bs4 import BeautifulSoup from lxml import etree 我们可以看见它的div和每个书的div框架,这样会观察会快速提高我们的简单爬取能力。 二.实…...

Linux系统编程(五)多线程创建与退出
目录 一、基本知识点二、线程的编译三、 线程相关函数1. 线程的创建(1)整型的传入与接收(2)浮点数的传入与接收(3)字符串的传入与接收(4)结构体的传入与接收 2. 线程的退出3. 线程的…...

计算机毕业设计 | SpringBoot个人博客管理系统(附源码)
1,绪论 1.1 背景调研 在互联网飞速发展的今天,互联网已经成为人们快速获取、发布和传递信息的重要渠道,它在人们政治、经济、生活等各个方面发挥着重要的作用。互联网上发布信息主要是通过网站来实现的,获取信息也是要在互联网中…...

字母的大小写转换
自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Python中,字符串对象提供了lower()方法和upper()方法进行字母的大小写转换,即可用于将大写字母转换为小写字母或者将小写字…...
JTW结构
JTW(JSON Web Token)的结构 在这篇笔记中,我们将了解JTW(JSON Web Token)的结构。我们将看到JTW是如何创建的,令牌的各个部分是什么,以及您如何自己构建和构造JTW。您还将了解一些这种结构的含义,以及使用JTW进行授权时的一些结果优缺点。 基本上,JTW本质上就是一个…...

debian11安装留档@VirtualBox
因为debian12无法安装tpot,所以又把11重新安装一遍,以前的安装文档:安装Debian 11 留档-CSDN博客 下载光盘 华为云地址:https://repo.huaweicloud.com/debian-cd/11.0.0/amd64/iso-cd/ 使用了debian11 教育版,比较有…...

SpringBoot——整合Thymeleaf模板
目录 模板引擎 新建一个SpringBoot项目 pom.xml application.properties Book BookController bookList.html 编辑 项目总结 模板引擎 模板引擎是为了用户界面与业务数据分离而产生的,可以生成特定格式的页面在Java中,主要的模板引擎有JSP&…...

电商推荐系统+电影推荐系统【虚拟机镜像分享】
电商推荐系统电影推荐系统【虚拟机镜像分享】 所有组件部署好的镜像下载(在下面),仅供参考学习。(百度网盘,阿里云盘…) 博主通过学习尚硅谷电商推荐电影推荐项目,将部署好的虚拟机打包成ovf文…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...

【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...

(转)什么是DockerCompose?它有什么作用?
一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用,而无需手动一个个创建和运行容器。 Compose文件是一个文本文件,通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
Java编程之桥接模式
定义 桥接模式(Bridge Pattern)属于结构型设计模式,它的核心意图是将抽象部分与实现部分分离,使它们可以独立地变化。这种模式通过组合关系来替代继承关系,从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

【C++进阶篇】智能指针
C内存管理终极指南:智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...