MyBatis 中为什么不建议使用 where 1=1?

3e076d871ee4b33c7d9595537c715e71.png

作者 | 王磊

来源 | Java中文社群(ID:javacn666)

转载请联系授权(微信ID:GG_Stone)

最近接手了一个老项目,“愉悦的心情”自然无以言表,做开发的朋友都懂,这里就不多说了,都是泪90783a2cdbdb19eb75f3fe9d11344fee.png...

接手老项目,自然是要先熟悉一下业务代码,然而在翻阅 mapper 文件时,发现了一个比较诡异的事情。这里给出简化后的业务代码:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><select id="list" resultType="com.example.demo.model.User">select * from userwhere 1=1<if test="name!=null">and name=#{name}</if><if test="password!=null">and password=#{password}</if></select>
</mapper>

机智的小伙伴可能已经看出了问题,在众多 mapper 中发现了一个相同的想象,几乎所有的 mapper 中都包含了一个无用的拼接 SQL:where 1=1。作为一个几乎有代码洁癖症的人,自然是忍不住动手改造一番了。

错误的改造方式

既然是去掉 where 1=1,那最简单的方式就是将它直接从代码中删除了,如下代码所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><select id="list" resultType="com.example.demo.model.User">select * from userwhere<if test="name!=null">name=#{name}</if><if test="password!=null">and password=#{password}</if></select>
</mapper>

以上代码删除了 1=1,并且把第一个 name 查询中的 and 去掉了,以防 SQL 查询报错。

但这样就没问题了吗?我们直接来看结果,当包含参数 name 查询时,结果如下:05117c2396325d130d5507d9b43fd298.png一切顺理成章,完美的一塌糊涂。 

然而,当省略 name 参数时(因为 name 为非必要参数,所以可以省略),竟然引发了以下异常:2bc3644630b565167dcea03e869c4f0b.png又或者只有 password 查询时,结果也是一样:3823940546ecf174afec372eb0d2da17.png都是报错信息,那肿么办呢?难不成把 1=1 恢复回去?

正确的改进方式

其实不用,在 MyBatis 中早已经想到了这个问题,我们可以将 SQL 中的 where 关键字换成 MyBatis 中的标签,并且给每个标签内都加上 and 拼接符,这样问题就解决了,如下代码所示:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper"><select id="list" resultType="com.example.demo.model.User">select * from user<where><if test="name!=null">and name=#{name}</if><if test="password!=null">and password=#{password}</if></where></select>
</mapper>

代码改造完成之后,接下来我们来测试一下所有的请求场景。

不传任何参数的请求

此时我们可以不传递任何参数(查询所有数据),如下图所示:55c45d6a4cd2a19625e474c025390c4c.png生成的 SQL 语句如下:c5f15109ec69a259dc215e29a7548c98.png

传递 1 个参数的请求

也可以传递 1 个参数,根据 name 进行查询,如下图所示:b85213b90fce609760838f41a062f492.png生成的 SQL 如下图所示:eaef2fb945e716d5d502b910a6833afb.png也可以只根据 password 进行查询,如下图所示:8edb38122fd55281a3ed9df6d9aa894a.png生成的 SQL 如下图所示:c4ea3b9dcdbce41d47190c3b349f4b9c.png

传递 2 个参数的请求

也可以根据 name 加 password 的方式进行联合查询,如下图所示:97bee97cc9b331ba90cd04be4bc9a034.png生成的 SQL 如下图所示:59fef979bb57f58b85b14d149ee745fc.png

用法解析

我们惊喜的发现,在使用了标签之后,无论是任何查询场景,传一个或者传多个参数,或者直接不传递任何参数,都可以轻松搞定。

首先,标签会判断,如果没有任何参数,则不会在 SQL 语句中拼接 where 查询,反之才会拼接 where 查询;其次在查询的标签中,每个标签都可以加 and 关键字,MyBatis 会自动将第一个条件前面的 and 关键字删除掉,从而不会导致 SQL 语法错误,这一点官方文档中也有说明,如下图所示:b77033036a2e1f5804403ce1e54a7b05.png

总结

在 MyBatis 中,建议尽量避免使用无意义的 SQL 拼接  where 1=1,我们可以使用标签来替代 where 1=1,这样的写既简洁又优雅,何乐而不为呢?以上内容仅为个人观点,欢迎评论区留言讨论。

a9d22a112eb66a367a4cfeb5227eabd5.gif

往期推荐

e13b32179b2b98d63d575ff79c5dfec5.png

MyBatis原生批量插入的坑与解决方案!


b9c541163fa9c03d057a848e8d158a98.png

MyBatis 批量插入数据的 3 种方法!


348ae7394043e9a637a0b2d56afa6fdb.png

SpringBoot官方热部署和远程调试神器,真带劲!


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/544484.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【openMV与机器视觉】四旋翼飞行控制背景下的PID控制与摄像头算法简介

文章目录声明1.四旋翼飞行控制简介2.飞行控制算法2.1.接收机PWM生成2.2.PID算法位置PID速度PID3.摄像头算法3.1.图像处理3.2.霍夫曼变换3.3.巡线算法3.3.寻找目标点降落算法声明 \qquad本文的算法在openMV IDE例程的基础上进行原创&#xff0c;在比赛结束后予以发表&#xff1b…

Java BigDecimal valueOf()方法与示例

BigDecimal类的valueOf()方法 (BigDecimal Class valueOf() method) Syntax: 句法&#xff1a; public static BigDecimal valueOf (double d);public static BigDecimal valueOf (long l);public static BigDecimal valueOf (long unsc_val , int sc_val);valueOf() method i…

关于liaoxuefeng的python3教程实战第四天

关于liaoxuefeng的python3教程实战第四天。地址&#xff1a;http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432338991719a4c5c42ef08e4f44ad0f293ad728a27b000#0编写数据访问代码接下来&#xff0c;就可以真正开始编写代码操作对象了…

聊聊sql优化的15个小技巧

前言sql优化是一个大家都比较关注的热门话题&#xff0c;无论你在面试&#xff0c;还是工作中&#xff0c;都很有可能会遇到。如果某天你负责的某个线上接口&#xff0c;出现了性能问题&#xff0c;需要做优化。那么你首先想到的很有可能是优化sql语句&#xff0c;因为它的改造…

没有安装node对等点依赖_功能依赖项的对等 数据库管理系统

没有安装node对等点依赖Equivalence of Functional dependencies states that, if the relations of different Functional dependencies sets are given, then we have to find out whether one Functional dependency set is a subset of other given set or both the sets a…

【MATLAB】Parzen窗与K近邻算法原理与代码详解

文章目录1.非参数估计原理2.Parzen窗2.1.算法原理2.2.Matlab实现与参数探究3.K近邻3.1.算法原理3.2.Matlab实现与参数探究1.非参数估计原理 \qquad已知一个样本的概率分布时&#xff0c;我们只需要对概率分布中的参数进行估计即可得到该样本的概率密度函数。例如已知样本X服从正…

使用 Lambda 表达式实现超强的排序功能

我们在系统开发过程中&#xff0c;对数据排序是很常见的场景。一般来说&#xff0c;我们可以采用两种方式&#xff1a;借助存储系统&#xff08;SQL、NoSQL、NewSQL 都支持&#xff09;的排序功能&#xff0c;查询的结果即是排好序的结果查询结果为无序数据&#xff0c;在内存中…

【mongodb系统学习之四】查看mongodb进程

四、查看mongodb进程&#xff08;可以配合启动和关闭使用&#xff09;&#xff1a; 1&#xff09;、方法一&#xff1a;直接查看mongodb进程是否已经存在&#xff08;用上面的方式启动后&#xff0c;需要另开一个窗口操作&#xff09;&#xff1a;ps –ef|grep mongodb, 如图&a…

kotlin 编译时常量_Kotlin程序| 编译时常量示例

kotlin 编译时常量编译时常数 (Compile-time Constant) If the value of a read-only (immutable) property is known at the compile time. 如果在编译时已知只读(不可变)属性的值。 Mark it as a compile-time constant using the const modifier. 使用const修饰符将其标记为…

【Simulink】粒子群算法(PSO)整定PID参数(附代码和讲解)

目录0.背景1.粒子群算法1.1.算法简介1.2.算法步骤1.3.算法举例2.PID自整定2.1.基于M文件编写的PID参数自整定*2.2.复杂系统的PID自整定&#xff08;基于simulink仿真&#xff09;2.2.1.PSO优化PID的过程详解2.2.2.在PSO优化过程中修改参数价值权重阅读前必看&#xff1a;本代码…

Microsoft.AspNet.Identity 自定义使用现有的表—登录实现

Microsoft.AspNet.Identity是微软新引入的一种membership框架,也是微软Owin标准的一个实现。Microsoft.AspNet.Identity.EntityFramework则是Microsoft.AspNet.Identity的数据提供实现。但是在使用此框架的时候存在一些问题&#xff0c;如果是全新的项目还可以使用它默认提供的…

stl vector 函数_vector :: front()函数以及C ++ STL中的示例

stl vector 函数C vector :: front()函数 (C vector::front() function) vector::front() is a library function of "vector" header, it is used to access the first element from the vector, it returns a reference to the first element of the vector. vect…

SpringBoot 使用注解实现消息广播功能

背景在开发工作中&#xff0c;会遇到一种场景&#xff0c;做完某一件事情以后&#xff0c;需要广播一些消息或者通知&#xff0c;告诉其他的模块进行一些事件处理&#xff0c;一般来说&#xff0c;可以一个一个发送请求去通知&#xff0c;但是有一种更好的方式&#xff0c;那就…

【Matlab】模式识别——聚类算法集锦

文章目录0.聚类分析简介0.1.简单的聚类样本生成器1.静态聚类算法1.1.最近邻聚类算法1.1.1.算法原理1.1.2.参考代码1.1.3.参数选择及运行结果1.2.最大最小距离法1.2.1.算法原理1.2.2.参考代码1.2.3.参数选择及运行结果2.动态聚类算法2.1.C均值聚类算法2.1.1.算法原理2.1.2.参考代…

Ant 风格路径表达式

ANT通配符有三种&#xff1a; 通配符说明?匹配任何单字符*匹配0或者任意数量的字符**匹配0或者更多的目录例子&#xff1a; URL路径说明/app/*.x匹配(Matches)所有在app路径下的.x文件/app/p?ttern匹配(Matches) /app/pattern 和 /app/pXttern,但是不包括/app/pttern/**/exam…

java string查找_查找输出程序(Java String类)

java string查找Program 1 程序1 public class iHelp{public static void main (String[] args){System.out.println("Google".charAt(3));}}Output 输出量 gExplanation 说明 String.charAt() is a library function of String class, it returns character from…

【MATLAB】混合粒子群算法原理、代码及详解

目录1.算法1.1.原理1.2.性能比较1.3.步骤2.代码2.1.源码及注释2.2.执行与效果1.算法 1.1.原理 \qquad建议没接触过粒子群算法的朋友先看较为基础的全局粒子群算法原理及介绍&#xff0c;以下博文链接有详细的讲解、代码及其应用举例&#xff1a; 【Simulink】粒子群算法&#…

MVC HtmlHelper用法大全

HtmlHelper用来在视图中呈现 HTML 控件。 以下列表显示了当前可用的一些 HTML 帮助器。 本主题演示所列出的带有星号 (*) 的帮助器。 ActionLink - 链接到操作方法。 BeginForm * - 标记窗体的开头并链接到呈现该窗体的操作方法。 CheckBox * - 呈现复选框。 DropDownList *…

基于 MyBatis 手撸一个分表插件

背景事情是酱紫的&#xff0c;上级leader负责记录信息的业务&#xff0c;每日预估数据量是15万左右&#xff0c;所以引入sharding-jdbc做分表。上级leader完成业务的开发后&#xff0c;走了一波自测&#xff0c;git push后&#xff0c;就忙其他的事情去了。项目的框架是SpringB…

密码学哈希函数_哈希函数在密码学中的应用

密码学哈希函数A Hash Function is a mathematical function that converts a numerical value into another compressed numeric value. The input value for the hash functions can be of arbitrary length, but the output text that it will produce will always be of fi…