mybatis ORA-00903: 表名无效
<select id= "queryTable" resultMap="map>
select * from #{tableName}
</select>
### SQL: select * from ?
### Cause: java.sql.SQLException: ORA-00903: 表名无效
发现有问题,实际上#{}方式通过?形式进行传递参数的,?它不支持tableName
将#{}换成${}
<select id= "queryTable" resultMap="map">
select * from ${tableName}
</select>
总结:
#{} :表示sql中的参数部分,实际上底层使用的是PreparedStatement
${}:表示字符串拼接,实际上底层采用的Statement对象
能使用#{}的地方都可以使用${}代替,但是能使用${}的地方不一定能够用#{}来替代
————————————————
版权声明:本文为CSDN博主「tornado430」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/tornado430/article/details/83001874
java中PreparedStatement和Statement详细讲解
大家都知道PreparedStatement对象可以防止sql注入,而Statement不能防止sql注入,那么大家知道为什么PreparedStatement对象可以防止sql注入,接下来看我的案例大家就会明白了!
我用的是mysql数据库,以admin表为例子,如下图:
最后面有具体的java代码和sql代码案例
最终执行的sql语句打印出来是SELECT * FROM admin WHERE username = '韦小宝' AND password = '222\' OR \'8\'=\'8'
从以上截图就能看出来,由此可见,prepareStatement对象防止sql注入的方式是把用户非法输入的单引号用\反斜杠做了转义,从而达到了防止sql注入的目的
Statement对象就没那么好心了,它才不会把用户非法输入的单引号用\反斜杠做转义呢!
PreparedStatement可以有效防止sql注入,所以生产环境上一定要使用PreparedStatement,而不能使用Statement
当然啦,你可以仔细研究下PreparedStatement对象是如何防止sql注入的,我自己把最终执行的sql语句打印出来了,看到打印出来的sql语句就明白了,原来是mysql数据库产商,在实现PreparedStatement接口的实现类中的setString(int parameterIndex, String x)函数中做了一些处理,把单引号做了转义(只要用户输入的字符串中有单引号,那mysql数据库产商的setString()这个函数,就会把单引号做转义)
————————————————
版权声明:本文为CSDN博主「冷囧囧」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/czh500/article/details/88202971