MyBatis中#{}和${}的区别详解

 更新时间:2016年08月18日 11:12:34   作者:jason.bai  
mybatis和ibatis总体来讲都差不多的。下面小编给大家探讨下mybatis中#{}和${}的区别,感兴趣的朋友一起学习吧

最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下.

先给大家介绍下MyBatis中#{}和${}的区别,具体介绍如下:

1. #将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是111,那么解析成sql时的值为order by "111", 如果传入的值是id,则解析成的sql为order by "id".

2. $将传入的数据直接显示生成在sql中。如:order by $user_id$,如果传入的值是111,那么解析成sql时的值为order by user_id, 如果传入的值是id,则解析成的sql为order by id.

3. #方式能够很大程度防止sql注入。 

4.$方式无法防止Sql注入。

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

6.一般能用#的就别用$.

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

字符串替换

默认情况下,使用#{}格式的语法会导致MyBatis创建预处理语句属性并以它为背景设置安全的值(比如?)。这样做很安全,很迅速也是首选做法,有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}

这里MyBatis不会修改或转义字符串。

重要:接受从用户输出的内容并提供给语句中不变的字符串,这样做是不安全的。这会导致潜在的SQL注入攻击,因此你不应该允许用户输入这些字段,或者通常自行转义并检查。

mybatis本身的说明:

String Substitution
By default, using the #{} syntax will cause MyBatis to generate PreparedStatement properties and set the values safely against the PreparedStatement parameters (e.g. ?). While this is safer, faster and almost always preferred, sometimes you just want to directly inject a string unmodified into the SQL Statement. For example, for ORDER BY, you might use something like this:
ORDER BY ${columnName}
Here MyBatis won't modify or escape the string.
NOTE It's not safe to accept input from a user and supply it to a statement unmodified in this way. This leads to potential SQL Injection attacks and therefore you should either disallow user input in these fields, or always perform your own escapes and checks. 

从上文可以看出:

1. 使用#{}格式的语法在mybatis中使用Preparement语句来安全的设置值,执行sql类似下面的:

PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1,id); 

这样做的好处是:更安全,更迅速,通常也是首选做法。

2. 不过有时你只是想直接在 SQL 语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用:

ORDER BY ${columnName} 

此时MyBatis 不会修改或转义字符串。

这种方式类似于:

Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql); 

这种方式的缺点是:

以这种方式接受从用户输出的内容并提供给语句中不变的字符串是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。

相关文章

  • Java之获取客户端真实IP地址的实现

    Java之获取客户端真实IP地址的实现

    在开发工作中,我们常常需要获取客户端的IP,本文主要介绍了Jav之获取客户端真实IP地址的实现,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • 基于SpringBoot+Avue实现短信通知功能

    基于SpringBoot+Avue实现短信通知功能

    Avue是基于vue和element-ui的快速开发框架 ,它的核心是数据驱动UI的思想,让我们从繁琐的crud开发中解脱出来,本文将给大家介绍一下使用SpringBoot+Avue实现短信通知功能,文中有详细的代码示例,需要的朋友可以参考下
    2023-09-09
  • 基于断点续传下载原理的实现

    基于断点续传下载原理的实现

    下面小编就为大家带来一篇基于断点续传下载原理的实现。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-09-09
  • java实现将结果集封装到List中的方法

    java实现将结果集封装到List中的方法

    这篇文章主要介绍了java实现将结果集封装到List中的方法,涉及java数据库查询及结果集转换的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2016-07-07
  • Spring MVC 4.1.3 + MyBatis零基础搭建Web开发框架(注解模式)

    Spring MVC 4.1.3 + MyBatis零基础搭建Web开发框架(注解模式)

    本篇文章主要介绍了Spring MVC 4.1.3 + MyBatis零基础搭建Web开发框架(注解模式),具有一定的参考价值,感兴趣的小伙伴们可以参考一下。
    2017-03-03
  • Java 汇编JVM编写jasmin程序的操作方法

    Java 汇编JVM编写jasmin程序的操作方法

    这篇文章主要介绍了Java 汇编JVM编写jasmin程序的操作方法,本文通过几个示例讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • Maven生成及安装jar包到本地仓库的方法

    Maven生成及安装jar包到本地仓库的方法

    这篇文章主要介绍了Maven生成及安装jar包到本地仓库的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-10-10
  • Java中的MapStruct的使用方法代码实例

    Java中的MapStruct的使用方法代码实例

    这篇文章主要介绍了Java中的MapStruct的使用方法代码实例,mapstruct是一种实体类映射框架,能够通过Java注解将一个实体类的属性安全地赋值给另一个实体类,有了mapstruct,只需要定义一个映射器接口,声明需要映射的方法,需要的朋友可以参考下
    2023-10-10
  • Java结构型模式之门面模式详解

    Java结构型模式之门面模式详解

    门面模式又叫外观模式(Facade Pattern),主要用于隐藏系统的复杂性,并向客户端提供了一个客户端可以访问系统的接口,本文通过实例代码给大家介绍下java门面模式的相关知识,感兴趣的朋友一起看看吧
    2023-02-02
  • Java中常用的设计模式之观察者模式详解

    Java中常用的设计模式之观察者模式详解

    这篇文章主要为大家详细介绍了Java中常用的设计模式之观察者模式,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-02-02

最新评论