- 一、使用 like 模糊查询
- 二、预编译和字符串替换
- 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”,如果传入的值是id,则解析成的sql为order by “id”。
$将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,如果传入的值是id,则解析成的sql为order by id。 - {}是预编译处理,$ {}是字符串替换。mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。
一、使用 like 模糊查询
1. 使用${…}
<if test="map.bank != '' and map.bank != null ">
and bank like '%${bank}%')
</if>
<!-- 错误的使用 -->
<if test="map.bank != '' and map.bank != null ">
and bank like '%${bank, jdbcType = VARCHAR}%')
</if>
由于$是参数直接注入的,导致这种写法,大括号里面不能注明jdbcType,不然会报错
后者会报错:org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named ‘VARCHAR’ in ‘class com.utry.ucsc.dao.bean.KnowledgeLibraryBean’
2. #{…}
<if test="map.bank != '' and map.bank != null ">
and b.bank like "%"#{bank, jdbcType = VARCHAR}"%")
</if>
因为#{…}解析成sql语句时候,会在变量外侧自动加单引号’ ‘,所以这里 % 需要使用双引号” “,不能使用单引号 ‘ ‘,不然会查不到任何结果。
3. 使用 concat 拼接
<if test="map.bank != '' and map.bank != null ">
and b.bank like concat('%',#{map.bank},'%')
</if>
二、预编译和字符串替换
在mybatis中#{}和${}的区别
解释1
将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by “111”,如果传入的值是id,则解析成的sql为order by “id”。
$将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id,如果传入的值是id,则解析成的sql为order by id。
字符串替换
默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:ORDER BY ${columnName}
这里MyBatis不会修改或转义字符串。
这种方式类似于:接受从用户输出的内容并提供给语句中不变的字符串(如下)。这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。
//这种方式类似于:
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
解释2
{}是预编译处理,$ {}是字符串替换。mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。
解释3
$ 符号一般用来当作占位符,常使用Linux脚本的人应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的。知道了这点就能很容易区分$和#,从而不容易记错了。
预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。
字符串替换的使用
- 使用QueryWrapper构造条件后,可以通过调用它的sqlSegment方法获得筛选条件,在sql中当做条件使用 ${qw.sqlSegment}
- 分库分表时,注入表名称等
- MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
- MyBatis中无法防止Sql注入