MyBatis#{}与${}区别与动态传入字段名问题解决

MyBatis动态传入字段名


一、 #{}与${}区别

#{}:占位符号,好处防止sql注入,相当于JDBC中的PreparedStatement
${}:是直接输出变量的值

简单说,#{}是经过预编译的,是安全的;SQLorderby {},那么不做任何处理的时候是存在SQL注入危险的。


二.、动态传入字段名解决方案

通过以上对#{}${}符号的比较,可以很清楚的知道#{}可以防止sql注入,并且是预编译的,所以想要动态传入字段名、表名使用#{}是不行的,只有使用非预编译的${}符号。

<select id="queryCar" resultType="CarsVo parameterType="java.util.Map">  
    SELECT
      *
    FROM
      cars c
    WHERE
      c. STATUS = #{status}
    ORDER BY
      #{sort} #{sort_type}
</select>

以上代码使用#{sort}在进行动态参数传入时,正如上文所讲会发生错误,通过sort得到的参数值会先预编译,从而不能实现传入一个字段名。


通过上述讲解,要想动态传入字段名或表名,则要使用${}符号,直接取得传来值。但是这样一来就会存在sql注入的风险,所以就必须得手工防止sql注入。


三、防止sql注入

SQL注入是一种代码注入技术,用于攻击数据驱动的应用,恶意的SQL语句被插入到执行的实体字段中(例如,为了转储数据库内容给攻击者)。

SQL注入,是一种常见的攻击方式。攻击者在界面的表单信息或URL上输入一些奇怪的SQL片段(例如“and ‘2’=’2’”这样的语句),从而入侵参数检验不足的应用程序。所以有必要在程序开发中,采用一些方式来防止该操作。在一些安全性要求很高的应用中(比如银行软件),经常使用将SQL语句全部替换为存储过程这样的方式,来防止SQL注入。

MyBatis框架作为一款半自动化的持久层框架,其SQL语句都要我们自己手动编写,因此相当需要防止sql注入。


根据上文所讲,#{}属于预编译,能够防止sql注入,所以在编写动态sql时,能使用#{}进行参数传递就尽量使用#{},如果不得已要使用${},就如动态传入字段名,就必须得自己手工进行防止sql注入代码的编写。如判断输入参数的长度是否正常(注入语句一般很长),更精确的过滤则可以查询一下输入的参数是否在预期的参数集合中。
如:

 <!--判断当前传入参数长度是否如预期参数长度相同。-->
 <if test="sort.length == 'creat_time'.length">
    ${sort}
 </if>   
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章