【MyBatis】原来 `${}` 和 `#{}` 藏有这么多坑!
一、引入
众所周知,MyBatis获取参数值的两种方式:${} 和 #{};${} 的本质就是字符串拼接,#{} 的本质就是占位符赋值。
${} 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是 #{} 使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号。
接下来考考大家,下面 ? 的地方应该填 $ 还是 #?(下面参数均为String类型)
▼xml复制代码select * from t_user where username like '%?{username}%'
▼java复制代码select * from t_user where username like "%"?{username}"%"
▼xml复制代码<if test="orderByList != null and orderByList.size() != 0"> ORDER BY <foreach collection="orderByList" separator="," item="orderByItem"> ?{orderByItem} </foreach> </if>
二、解释
第一个案例应为 $,解释:
由于我们使用的是模糊查询,%#{username}% 需要写在一对单引号中,单引号在mysql中表示的是一个字符串;当我们用 #{} 时,并且在执行时,? 会代替 #{} 的时候,? 就存在了 #{} 里面,这个时候就会把 ? 当做字符串的一部分,因此应该使用 ${} 进行字符串拼接
▼xml复制代码select * from t_user where username like '%${username}%'
第二个案例应为 #,解释:
▼xml复制代码select * from t_user where username like "%"#{username}"%"
假设传入的参数 username 的值是 john,使用占位符后的 SQL 语句:
▼java复制代码SELECT * FROM t_user WHERE username LIKE "%john%"
在这种情况下,#{username} 会直接被替换为参数值,而不加引号。
因此,替换后是 "%john%",而不是 "%""%john%""%"。
第三个案例应为 $,
▼java复制代码<if test="orderByList != null and orderByList.size() != 0"> ORDER BY <foreach collection="orderByList" separator="," item="orderByItem"> ${orderByItem} </foreach> </if>
这是因为如果使用 #{},那么在SQL解析的时候会加上单引号,假设传入的值为 create_time desc, userId desc,那么SQL解析后的结果就为
▼xml复制代码ORDER BY 'create_time desc, userId desc'
此时排序是不生效的,因此需要使用 ${} 让它不自动加单引号
▼xml复制代码ORDER BY create_time desc, userId desc
评论
问答助学
相关内容
0个评论
全部评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
