• Mybatis中${}和#{}的区别


    前言

    MyBatis中动态sql是其主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在执行操作之前 mybatis 会对其进行动态解析。

    MyBatis提供了两种支持动态 sql 的语法:#{} 以及 $ {},其最大的区别则是#{}方式能够很大程度防止sql注入(安全),${}方式无法防止Sql注入。


    SQL注入

    ${}方式是将形参和SQL语句直接拼接形成完整的SQL命令后,再进行编译。所以可以通过设计形参变量的值,从而改变SQL语句产生安全隐患,即为SQL注入攻击。举例说明:
    在Mapper映射文件中:

    <select id="findByName" parameterType="String" resultMap="ResultMap">
            SELECT * FROM user WHERE username='${value}'
        select>
    

    当username=" ‘or 1=1 or’ "传入后,${}将变量内容直接和sql语句进行拼接。

    SELECT * FROM user WHERE username='' OR 1=1 OR '';
    

    该跳语句可以将整个数据库用户内容暴露出来。

    #{}方式则是先用占位符代替参数将SQL语句先进行编译,然后再讲参数中的内容替换进去。因为SQL语句已经被预编译过,其SQL意图将无法通过非法的参数内容实现更改,其参数中的内容,无法变为SQL命令的一部分。
    故,#{}可以防止SQL注入而${}却不行


    关于#{}

    • #{}表示一个占位符,相当于jdbc中的?符号
    • 当#{}传入的数据是一个字符串时,会自动将传入的数据加一个双引号。
      比如:SELECT * FROM user WHERE username=#{value},如果传入的值是bbq,那么解析成sql时的值就是where username=“bbq”
    • 如果sql语句中只有一个参数,此时参数名称可以随意定义。如果sql语句有多个参数,此时参数名称应该是与当前表关联[实体类的属性名]或则[Map集合关键字],不能随便写,必须对应

    关于${}

    • $ {}将传入的数据直接显示生成在sql中。如:select * from user where id= $ {user_id},如果传入的值是1006,那么解析成sql时的值为where id=1006
    • $ {value}中value值有限制只能写对应的value值不能随便写,因为${}不会自动进行jdbc类型转换
    • 在JDBC不支持使用占位符的地方,都可以使用${}

    总结

    • 如果在sql语句中动态指定表名或列名时,只能使用${}
    • MyBatis排序时order by 动态参数时,只能使用${}
    • MyBatis能使用#{}的时候尽量使用#{}
    • #{}不需要关注数据类型,mybatis实现自动数据类型转换;${}不做数据类型转换,需要自行判断数据类型;
  • 相关阅读:
    虚拟机备份
    CD206抗体载Fe3O4的PLGA纳米微球/多烯紫杉醇-PLGA纳米粒的制备研究
    万古霉素修饰银纳米粒/磁性纳米微球/负载万古霉素PLGA缓释微球/硅包银纳米三角片
    快照隔离,与Percolatory分布式解决方案
    CTF是黑客大赛?新手如何入门CTF?
    SystemServer是如何启动AMS的
    聊聊基于Alink库的随机森林模型
    一种基于超像素和生成对抗网络的视网膜血管分割方法
    WPF基础的一些基本操作
    SpringBoot Cors配置+原理分析(corsfilter)
  • 原文地址:https://blog.csdn.net/BBQ__ZXB/article/details/127089187