工作发狂:Mybatis 中$和#千万不要乱用!

news/2024/7/3 2:58:19

点击上方“方志朋”,选择“置顶公众号”

技术文章第一时间送达!

开头

这是一次代码优化过程中发现的问题,在功能优化后发现部分数据查不到出来了,问题就在于一条sql上的#和$。

下图为两条sql:

从图上可以看出 wwlr.LabelId in(${showLabels}) 和 wwlr.LabelId in(#{showLabels}),其中showLabels是传进来一个字符串类型的参数,参数的样子是这样的“4,44,514”,问题就出在这个参数传进来后#和$处理的方式是不一样的。

区别

1、#{ }是预编译处理,MyBatis在处理#{ }时,它会将sql中的#{ }替换为?,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两边加上单引号,如上面的值 “4,44,514”就会变成“ '4,44,514' ”;

2、${ }是字符串替换, MyBatis在处理${ }时,它会将sql中的${ }替换为变量的值,传入的数据不会加两边加上单引号。

注意:使用${ }会导致sql注入,不利于系统的安全性!

SQL注入:就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。常见的有匿名登录(在登录框输入恶意的字符串)、借助异常获取数据库信息等

应用场合:

1、#{ }:主要用户获取DAO中的参数数据,在映射文件的SQL语句中出现#{}表达式,底层会创建预编译的SQL;

2、${ }:主要用于获取配置文件数据,DAO接口中的参数信息,当$出现在映射文件的SQL语句中时创建的不是预编译的SQL,而是字符串的拼接,有可能会导致SQL注入问题.所以一般使用$接收dao参数时,这些参数一般是字段名,表名等,例如order by {column}。

注:

${}获取DAO参数数据时,参数必须使用@param注解进行修饰或者使用下标或者参数#{param1}形式;

#{}获取DAO参数数据时,假如参数个数多于一个可有选择的使用@param。

问题分析

其实刚开始我也没太去看sql里的#和$,我把sql放到数据库跑一切正常,所以我就将代码的执行sql输出到控制台了,具体是这么一个输出sql的配置文件:

输出后,终于发现了问题在哪里。。。。

看了上面的区别介绍,相信大家其实都应该知道区别在哪里,我们的问题在哪里,其实就是sql在in的时候 ,里面的数据被加了两个双引号。“wwlr.LabelId in(4,44,514)就会变成 wwlr.LabelId in('4,44,514' );所以导致部分数据查不到了。

解决办法

1、快速解决

最快的方法就是把#直接替换成$,这样问题应该就可以解决了。

但是,我很无语,我确没有解决。

本地跑代码一点问题都没有,部署到公司的docker上问题一样没解决,给人的感觉就是代码根本没有从#变$。

大家都知道$其实是有危险性,会容易被sql注入,具我所知道,我们公司的docker是会加一层防止 sql注入的功能 ,所以不知道是不是这个功能把的$无效掉了。

当然,我也没有去再到服务上打出sql来看一下,因为本来$就是不太安全的,所以我换了一种方式处理。

2、foreach标签的使用

foreach标签主要用于构建in条件,他可以在sql中对集合进行迭代。

先来看看语法:

通过上图,大家也应该也了解和使用这个标签了吧。

那对于我们项目中的改造,其实就是把原来传进来的字符型参数变成List<Integer>,这样问题就完美的解决了,既实现了我们的功能 ,又解决了安全性问题。

原文链接:

https://m.toutiaocdn.com/i6685496024770806280

热门内容:

  • 淘宝服务端高并发分布式架构演进之路

  • 有没有想过,手写一个连接池?

  • 一个Java对象到底有多大?

  • Spring Cloud Alibba教程:如何使用Nacos作为配置中心

  • Spring Cloud Alibaba教程:使用Nacos作为服务注册中心

           感谢搓一下“在看


http://lihuaxi.xjx100.cn/news/279666.html

相关文章

[C#,Java,PHP] - IMAP文件夹名称编码和解码方法

[C#] 来源&#xff1a;http://www.oschina.net/code/snippet_110991_2237 // 编码private string IMAPEncode(string folder){string rtn "", base64;int index 0; Regex regAsis new Regex("\G(?:[\x20-\x25\x27-\x7e])"); Regex reg26 new Rege…

NB-Iot烟感01:烟感探测器原理和规格

一、烟感探测器分类和工作原理 感烟探测器: 俗称 烟雾探测器&#xff0c;这个产品我们到处都可以看到&#xff0c;不管是地铁站&#xff0c;还是办公楼&#xff0c;商城&#xff0c;宾馆、商店、仓库、机房、住宅等我们抬头就可以看到。也被称为感烟式火灾探测器、烟感探测器、…

那个14岁上大学、17岁读博、24岁当教授的天才神童,如今怎么样了?

陶哲轩最令人羡慕之处&#xff0c;不在于惊人的天赋和出色的成就&#xff0c;而在于坐拥这些天才和成就的同时&#xff0c;也能成长为一个享有健康生活的快乐的“普通人”。世界上最聪明的人是谁&#xff1f;一些媒体报道可能会将这个答案引向一位华裔男性——陶哲轩。据说&…

时隔15 年,Glibc引入Linux的arc4random函数

时隔 15 年&#xff0c;Glibc 终于引入了用于 Linux 的 arc4random 函数,glibc是GNU发布的libc库&#xff0c;即c运行库。glibc是linux系统中最底层的api&#xff0c;几乎其它任何运行库都会依赖于glibc。 近日的一个提交显示&#xff0c;GNU C 库 (Glibc) 终于添加了用于 Linu…

对抗图像和攻击在Keras和TensorFlow上的实现

点击上方“小白学视觉”&#xff0c;选择加"星标"或“置顶”重磅干货&#xff0c;第一时间送达本文转自&#xff1a;计算机视觉联盟AI博士笔记系列推荐周志华《机器学习》手推笔记正式开源&#xff01;可打印版本附pdf下载链接[ 摘要 ]在这篇教程中&#xff0c;你将会…

java中Volatile修饰符的含义

在java语言中&#xff1a;为了获得最佳速度&#xff0c;同意线程保存共享成员变量的私有拷贝。并且仅仅当线程进入或者离开同步代码块时才与共享成员变量的原始值进行对照。 volatilekeyword的作用就是提示vm&#xff1a;对于这个成员变量不能保存它的私有拷贝。而应直接与共享…

边界框的回归策略搞不懂?算法太多分不清?看这篇就够了

作者 | fivetrees来源 | https://zhuanlan.zhihu.com/p/76477248本文已由作者授权&#xff0c;未经允许&#xff0c;不得二次转载【导读】目标检测包括目标分类和目标定位 2 个任务&#xff0c;目标定位一般是用一个矩形的边界框来框出物体所在的位置&#xff0c;关于边界框的回…

你的Redis怎么持久化的

引言(本文改编自生活真实案例&#xff0c;如有类同&#xff0c;绝不是巧合&#xff01;)端午节&#xff0c;烟哥正在一边愉快的学习….突然&#xff0c;微信一阵抖动。原来是老刘呼唤烟哥&#xff01;善良的烟哥本以为人家是要约我出去玩&#xff01;然而&#xff0c;打开微信一…