mybatis ${ } 和 #{ } 的区别

    动态 sql 是 mybatis 的主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在查询之前 mybatis 会对其进行动态解析。mybatis 为我们提供了两种支持动态 sql 的语法:#{} 以及 ${}。

1 .#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号  而   $将传入的数据直接显示生成在sql中

例如:  

          (1)order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为                        order by "id".

               order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by 111, 如果传入的值是id,则解析成的sql为                            order by id.

          (2)  如果传入的name 是zhangsan

            select * from user where name = #{name};

               select * from user where name = ${name}; 

              解析结果一样 为:select * from user where name = 'zhangsan';

2.   #{}是预编译处理,${}是字符串替换

例如:(1)select * from user where name = #{name};

           mybatis在处理#{}时,会将sql中的#{}替换为 ? 号,调用PreparedStatement的set方法来赋值

           结果为: select * from user where name= ?

           (2) select * from user where name = ${name};

            字符串替换 结果为(如果name 是 zhangsan):

              select * from user where name = 'zhangsan'

3.     优先使用 #{}。因为 ${} 会导致 sql 注入的问题

         原因:#{} 采用的是预编译机制,预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生 影响,从而避免了潜在的安全风险。

我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作 所以 ${}可以出现sql注入问题。

例如:

       select * from ${tableName} where name = #{name}
        如果表名  user; delete user; -- 

        则动态解析之后 sql 如下:

        select * from user; delete user; -- where name = ?;

        --之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,            极大可能导致服务器宕机。

        (如果不理解sql 注入 请看链接:)https://blog.csdn.net/u012436758/article/details/53871290

4. $方式一般用于传入数据库对象,例如传入表名 字段 等

5. MyBatis排序时使用order by 动态参数时需要注意,用$而不是#

 

 

 

 

            

 

 

 

你可能感兴趣的:(mybatis ${ } 和 #{ } 的区别)