(转)mybatis中#和$的区别

转载至:前端

http://www.javashuo.com/article/p-tuzcfysg-hr.htmlsql

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

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

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

  而后,预计它的输出应该是相似于下面这样的调试

ORDER BY columnName desccode

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

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

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

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中#和$绑定参数的区别作个总结,避免之后相似的问题发生。

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

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

  3. #方式可以很大程度防止sql注入。

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

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

  6. 通常能用#的就别用$.

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

相关文章
相关标签/搜索