Java教程

Java开发MySQL中#{} 和 ${}的区别

本文主要是介绍Java开发MySQL中#{} 和 ${}的区别,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

梗概

#{}: 占位符号,可以防止sql注入,自己会带有双引号;

${}:sql拼接符号,存在sql注入问题,需要在代码中过滤以避免注入,不会带有双引号;

MyBatis排序使用order by 动态参数时,用${}而不是#{}。

详细区别

#{}:

SELECT * FROM user WHERE name = #{nameParam};

解析为一个JDBC预编译语句后:

SELECT * FROM user WHERE name = ?;

即#{} 解析为?,当 nameParam = "Bob" 时:

SELECT * FROM user WHERE name = "Bob"; //带有引号

${}:

SELECT * FROM ${tableNameParam};

${}是一个纯粹的string替换,动态解析时,会进行变量替换,不带有引号,当tableNameParam= "user" 时:

SELECT * FROM user

即预编译之前SQL中就已经不包含变量,而是被替换成常量数据了

[ sql预编译]  sql 预编译指的是数据库驱动在发送 sql 语句和参数给 DBMS 之前对 sql 语句进行编译,这样 DBMS 执行 sql 时,就不需要重新编译。


详细部分小结

#{}变量的替换是在DBMS中,而${}变量的替换是在动态SQL解析阶段


使用小诀窍

优先使用#{},即能用#{}就用#{}:

1、从性能方面考虑,相同的预编译sql可以重复利用

2、${}在预编译之前就已经被替换为常量,会存在sql注入问题


表名作为变量时,必须用${}:

SELECT * FROM #{tableNameParam}

预编译完成后,sql变为:

SELECT * FROM ?

当参数tableNameParam = "user" 时,sql变为

SELECT * FROM 'user'

这会导致 sql 语法错误,表名不能加单引号 ''(反引号 ``是可以的)。


当用${}时:

SELECT * FROM ${tableNameParam}

同样当参数tableNameParam = "user" 时,sql变为:

SELECT * FROM user

同样的道理,ORDER BY排序时,也只能用${}


sql注入:

SELECT * FROM ${tableNameParam} WHERE name = #{nameParam};

假设上如sql语句,tableNameParam = user; delete user; -- 还有 nameParam = Bob,那么编译前:

SELECT * FROM user; delete user; -- WHERE name = ?;

动态编译完成后:

SELECT * FROM user; delete user; -- WHERE name = "Bob";

那么实际执行的sql一共两句:

SELECT * FROM user;
delete user;

而 -- 之后的语句会被作为注释,不起作用;这时本来的一条查询语句,被注入了一个删除表数据的SQL。

这篇关于Java开发MySQL中#{} 和 ${}的区别的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!