1.#{} 和 ${} 的使用
1.1参数为Integer类型
观察打印日志:
输⼊的参数并没有在后⾯拼接,id的值是使⽤ ? 进⾏占位. 这种SQL 我们称之为"预编译SQL"
将 #{} 改为 ${}:
观察打印的日志:
即时SQL
1.2参数为String类型
打印日志:
将 #{} 改为 ${}:
打印日志:
参数依然是直接拼接在SQL语句中了, 但是字符串作为参数时, 需要添加引号 ’ ’ , 使⽤ ${} 不会拼接引号 ’ ’ , 导致程序报错:
2.#{} 和 ${} 的区别
#{} 使⽤的是预编译SQL, 通过 ? 占位的⽅式, 提前对SQL进⾏编译, 然后把参数填充到SQL语句中。 #{} 会根据参数类型, ⾃动拼接引号 ‘’ ;${} 是直接进⾏字符替换, ⼀起对SQL进⾏编译. 如果参数为字符串, 需要加上引号 ‘’。
- #是预编译SQL,$是即时SQL,#性能更高
绝⼤多数情况下, 某⼀条 SQL 语句可能会被反复调⽤执⾏, 或者每次执⾏的时候只有个别的值不同(⽐如 select 的 where ⼦句值不同, update 的 set ⼦句值不同, insert 的 values 值不同)。如果每次都需要经过上⾯的语法解析, SQL优化、SQL编译等,则效率就明显不⾏了。
预编译SQL,编译⼀次之后会将编译后的SQL语句缓存起来,后⾯再次执⾏这条语句时,不会再次编译(只是输⼊的参数不同), 省去了解析优化等过程, 以此来提⾼效率。
- $ 存在SQL注入的风险
SQL注⼊:是通过操作输⼊的数据来修改事先定义好的SQL语句,以达到执⾏代码对服务器进⾏攻击的⽅法。
sql 注⼊代码: ’ or 1='1
$的使用场景:
- 排序功能
此处 order 参数为String类型, 但是SQL语句中, 排序是不需要加引号 ‘’ 的, 使⽤ #{order} 查询时, desc 前后⾃动给加了引号, 导致 sql 错误:
改为$:
除此之外, 还有表名,字段名作为参数时, 也只能使⽤ ${}。
- like查询
使用#:
改为$:
把 #{} 改成
可以正确查出来
,
但是
{} 可以正确查出来, 但是
可以正确查出来,但是{}存在SQL注⼊的问题, 所以不能直接使⽤ ${}。
解决办法: 使⽤ mysql 的内置函数 concat() 来处理,实现代码如下: