动态 sql 是 MyBatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 MyBatis 会对其进行动态解析。MyBatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。
#{}和${}的区别
(1) #{}是预编译处理动态解析之后会将传入的变量加上双引号,$ {}是字符串替换不会加双引号。
(2) MyBatis在处理#{}时,会将SQL中的#{}替换为?号,使用PreparedStatement的set方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。
(3) 使用 #{} 可以有效的防止SQL注入,提高系统安全性。
(4) 使用Preparedstatement的预编译机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。而预编译机制则可以很好的防止SQL注入。在某些特殊场合下只能用${},不能用#{}。例如:在使用排序时ORDER BY ${id},如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法。
<select id="selectUser" parameterType="int" resultType="user">
SELECT id,name,password FROM user WHERE password = #{password}
</select>
假如传入密码为123456,在解析时就会解析成SELECT id,name,password FROM user WHERE password = “123456”(带双引号)
<select id="selectUser" parameterType="int" resultType="user">
SELECT id,name,password FROM user WHERE password = ${password}
</select>
假如传入密码为123456,在解析时就会解析成SELECT id,name,password FROM user WHERE password = 123456(不带双引号)
使用mysql中mybatis的模糊查询
千万千万不要写成
<select id="selectUser" parameterType="int" resultType="user">
SELECT id,name,password FROM user WHERE name LIKE "%#{password}%"
</select>
因为动态解析完之后数据库得到的sql是这样的 SELECT id,name,password FROM user WHERE name LIKE “%“小”%”,毫无疑问这样的sql语句肯定是错误的。
下面这才是正确的写法:
<select id="selectUser" parameterType="int" resultType="user">
SELECT id,name,password FROM user WHERE name LIKE concat("%",${password},"%")
</select>
假如传入name为 小 ,在动态解析之后会变成 SELECT id,name,password FROM user WHERE name LIKE “%小%”,会将数据库中名字中包含 小 的信息查询出来
concat函数
CONCAT(字串1, 字串2, 字串3, …): 将字串1、字串2、字串3,等字串连在一起。