-
Notifications
You must be signed in to change notification settings - Fork 0
#{}与${}有啥不同?从源码的角度来分析!
GenericTokenParser.java line:19 parse(String text)方法中,就是解析${}占位符的。
如:SELECT * FROM USER_${index} WHERE NAME=#{name} AND age=#{age}
在parse方法中通过定位开始符号:${, 结束符号:},并把相应参数设置进去,sql变成如下:
SELECT * FROM USER_1 WHERE NAME=#{name} AND age=#{age}
SqlSourceBuilder.java line:31中,parse(String originalSql, Class<?> parameterType, Map<String,Object>
additionalParameters),执行#{}的解析。
把sql从上一步:SELECT * FROM USER_1 WHERE NAME=#{name} AND age=#{age}
变成了:
SELECT * FROM USER_1 WHERE NAME=? AND age=?
是不是很熟悉?对了,这就是jdbc认识的sql。
接下来就可以使用:PreparedStatement.set方法设置参数啦!
从这里,看出两者的区别:
#{} : 参数采用预编译方式,可以防止SQL注入
${}: 参数采用直接赋值方式,无法阻止SQL注入攻击
但是并不是所有地方都能使用#{}, jdbc不支持占位符的场合,只能用${}.如以下两种情况:
1.动态指定数据库表:
select * from emp_${year}
2.需要动态的指定查询中的排序字段,此时也只能使用${} select * from dept order by ${name}
并且缓存的key是用SELECT * FROM USER_1 WHERE NAME=? AND age=? 这种形式 加参数 这种形式的,所以能看出来,