天天看点

Mybatis中#和$的区别结合实际问题考虑的另一篇博文

被人问到过#和$的区别:回答的模棱两可

当时只是知道这俩一个可以防止SQL注入一个传值,类似于建立数据库连接时的编译SQL语句的statement和PrepareStatement一样。

正好发现网上有哥们写的比较详细。比较了几篇后,就直接转载过来,分享给大家,也当做自己的一个笔记。

一 .#与$区别说通俗一点就是

         $中间的变量就是直接替换成值的

         #会根据变量的类型来进行替换

         比如articleTitle的类型是string, 值是"标题"的时候

              $articleTitle$ = 标题

              #articleTitle# = '标题'



二. $ 的作用实际上是字符串拼接,

         select * from  $tableName$

         等效于

         StringBuffer sb = new StringBuffer();

         sb.append("select * from").append(tableName);

         sb.toString();


        #用于变量替换

        select * from table where id = #id#

        等效于

        prepareStement =stmt.createPrepareStement("select * from table where id = ?")

        prepareStement.setString(,'abc'); 





三.那什么时候用$,什么时候 用 #

       ()对于变量部分, 应当使用#, 这样可以有效的防止sql注入,具体执行时,# 都是用到了prepareStement,这样对效率也有一定的提升

            #方式一般用于传入插入/更新的值或查询/删除的where条件

       () $只是简单的字符拼接而已,对于非变量部分, 那只能使用$, 实际上, 在很多场合,$也是有很多实际意义的

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

             例如:

             select  *  from  $tableName$  对于不同的表执行统一的查询

             update  $tableName$  set  name = #name#  每个实体一张表,改变不用实体的状态

             特别说明, $只是字符串拼接,所以要特别小心sql注入问题。

      ()能同时用#和$的时候最好用#
           

结合实际问题考虑的另一篇博文

今天在工作中有个点击排序的功能调试了许久,终寻因,总结之。 
  需求是这样的,页面有个table,有一列的上下箭头可点击并排序。对于这种需求,我的mybatis.xml的sql配置写成了如下:

<if test="map.ColumnNameSort!=null and map.ColumnNameSort!=''"> 
  ORDER BY columnName #{map.ColumnNameSort} 
</if>

  ColumnNameSort即前端传的排序方式,asc或者desc。

  然后,预计它的输出应该是类似于下面这样的

ORDER BY columnName desc

  但是,真正跑起来时,排序的效果一直没出现,经常一番查找,发现是mybatis 的’#{}’传值的问题,它将sql语句编译成了如下

ORDER BY columnName 'desc' 或者 ORDER BY columnName 'asc'

  这样,desc或者asc就成了字符串而不是关键字,sql语句的意思是columnName的别名是desc或者asc,没加排序关键字时默认是正序排序,成了如下

ORDER BY columnName "desc" asc 或者 ORDER BY columnName "asc" asc

  排序没效果的问题找到原因了,解决之,mybatis提供了另一种绑定参数的方式–${param},将sql配置改为

ORDER BY columnName ${map.ColumnNameSort}

  这样一来,mybatis会直接将ColumnNameSort的值加入sql中,不会转义。正确结果:

ORDER BY columnName desc

  最后,对于mybatis中#和$绑定参数的区别做个总结,避免以后类似的问题发生。

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

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

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

$方式无法防止Sql注入。

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

一般能用#的就别用$.

ps:在使用mybatis中还遇到<![CDATA[]]>的用法,在该符号内的语句,将不会被当成字符串来处理,而是直接当成sql语句,比如要执行一个存储过程。
           

第一篇博文:转载地址:https://blog.csdn.net/jinglingline/article/details/78929994

第二篇博文:转载地址:https://blog.csdn.net/u011519624/article/details/54674670

继续阅读