场景
拼接sql语句执行like查询
解决方案
1、将单个单引号('
),替换为两个(''
)
2、自定义Escape字符比如(/
)
3、给关键字符(\_,%,[,]
)加前缀Escape字符(/\_,/%,/[,/]
)
4、最终sql语句的like部分类似 like 'ni''hao/_wor/%ld' Escape '/'
使用 StringEscapeUtils
添加依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.6</version>
</dependency>
package com.baobaotao.escape;
import org.apache.commons.lang.StringEscapeUtils;
public class SqlEscapeExample {
public static void main(String[] args) {
String userName = "1' or '1'='1";
String password = "123456";
userName = StringEscapeUtils.escapeSql(userName);
password = StringEscapeUtils.escapeSql(password);
String sql = "SELECT COUNT(userId) FROM t_user WHERE userName='"
+ userName + "' AND password ='" + password + "'";
System.out.println(sql);
}
}
事实上, StringEscapeUtils 不但提供了 SQL 特殊字符转义处理的功能,还提供了 HTML、XML、JavaScript、Java 特殊字符的转义和还原的方法。
注:StringEscapeUtils其实只将单个单引号('
),替换为两个(''
),如果要解决其他的通配符建议用StingUtils.replace(str, searchString, replaceString)
来替换。
mybatis模糊查询防止SQL注入
#{}进行预编译,传递的参数不进行编译,只作为参数,相当于PreparedStatement
bind 元素可以从 OGNL 表达式中创建一个变量并将其绑定到上下文。比如:
<select id="selectBlogsLike" resultType="Blog">
<bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />
SELECT * FROM BLOG
WHERE title LIKE #{pattern}
</select>
关于通配符的问题
MySql
的like语句中的通配符:百分号(%
)、下划线(_
)和escape
Oracle
的like语句中的通配符:
%(百分号):用来表示任意数量的字符,或者可能根本没有字符。
_(下划线):表示确切的未知字符。
?(问号):用来表示确切的未知字符。
#(井号):用来表示确切的阿拉伯数字,0到9。
[a-d](方括号):用来表示字符范围,在这里是从a到d。
单引号('):在Oracle中,应该只使用单引号将文本和字符和日期括起来,不能使用引号(包括单双引号)将数字括起来。
双引号("):在Oracle中,单双引号含义不同。双引号被用来将包含特定字符或者空格的列别名括起来。双引号还被用来将文本放入日期格式。
撇号('):在Oracle中,撇号也可以写成彼此相邻的两个单引号。为了在供应商名字中间查找所有带撇号的供应商名字,可以这样编写代码:
select * from l_suppliers where supplier_name like '%''%'
&符号:在Oracle中,&符号常用来指出一个变量。例如,&fox是一个变量,稍微有点不同的一种&& fox。每当&fox出现在Oracle脚本中时,都会要求您为它提供一个值。而使用&&fox,您只需要在& &fox第一次出现时为它提供变量值。如果想将&符号作为普通的符号使用,则应该关闭这个特性。要想关闭这个特性,可以运行以下的命令: set define off ,这是一个SQLplus命令,不是一个SQL命令。SQLplus设置了SQL在Oracle中运行的环境。
双竖线(||):Oracle使用双竖线表示字符串连接函数。
星号(*):select *意味着选择所有的列,count(*)意味着计算所有的行,表示通配符时,表示0个或任意多个字符。
正斜杠(/):在Oracle中,用来终止SQL语句。更准确的说,是表示了“运行现在位于缓冲区的SQL代码”。正斜杠也用作分隔项。
多行注释:/*......*/。
不等于:有多种表达方式:!=、^=、<>、not xxx=yyy、not(xxx=yyy)
参考文献:
1、https://blog.51cto.com/zfeng/1783001 20200511
2、https://www.jianshu.com/p/869cec655ed9 2020511