#{}和${}的区别是什么?
#{}
:是预编译处理,可以防止SQL注入
${}
:是字符串替换
例如:
在Mybatis中当你进行数据库查询时SQL语句通过#{id}
传值
<select id="SelecUserById" resultType="com.hanson.pojo.User" parameterType="int">
select *from user where id=#{id};
</select>
当你执行项目时,我们通过log4j打印日志出来可以看到
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 764577347.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@2d928643]
DEBUG [main] - ==> Preparing: select *from user where id=?;
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
他会先执行
select *from user where id=?;
再通过#{id}
传值进行数据库查询
如果你用${}
进行传值
<select id="SelecUserById" resultType="com.hzc.pojo.User" parameterType="int">
select *from user where id=${id};
</select>
会报一个错误,提示你id类型错误,因为${}把int类型的id转化成String类型的id
解析成的sql为:select * from user where id= “id”
Exception in thread "main" org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer'
### Cause: org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'id' in 'class java.lang.Integer'
${}通常再EL表达式中使用,用来展示后端传递到前端的值
总结
#{}
是预编译处理,$ {}
是字符串替换。
-
mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
-
mybatis在处理 $ { } 时,就是把 ${ } 替换成变量的值。使用 #{} 可以有效的防止SQL注入,提高系统安全性。
$ 符号一般用来当作占位符,常使用Linux脚本的人应该对此有更深的体会吧。既然是占位符,当然就是被用来替换的。知道了这点就能很容易区分$和#,从而不容易记错了。
预编译的机制。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入