问题描述

@Select("select * from account order by #{orderBy} #{orderRule} limit #{start},#{offset}")
public List<Account> getAccountList(@Param("orderBy") String orderBy, @Param("orderRule") String orderRule,
@Param("start) int start, @Param("offset") int offset);

如上代码所示,在执行查询操作时,为了能够与前端联动进行排序,直接在SQL参数中传递排序字段和排序规则。

但是,在调试时偶然发现,当传递的“orderBy”值为不存在的字段时,竟然不会报错!!!

经过进一步调试发现,实际上并不会按照预期的排序规则返回数据列表!!!

原因追踪

设置log4j的日志级别为DEBUG后发现,最终执行的SQL语句是一个预编译操作,mybatis输出日志如下:

==>  Preparing: select * from account order by ? ? limit ?, ?
==> Parameters: loginName(String), DESC(String), 0(Integer), 50(Integer)

很显然,传递的参数loginName和DESC是作为字符串处理的。

也就是说,很有可能mybatis对String类型的参数会进行转换。举个例子:传递的String参数为loginName,最终在SQL语句执行时为:'loginName'。

再进一步验证,如果在SQL语句中传递的排序字段不是字段名loginName,而是'loginName'时,是不会按照排序规则返回数据的,并且也不会报错!

追溯mybatis官方文档发现:默认情况下,使用#{}格式的语法会导致mybatis对字符串进行修改或转义!!!



详见:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html#select

解决问题

将参数传递的语法格式#{}修改为${},即:

@Select("select * from account order by ${orderBy} ${orderRule} limit #{start},#{offset}")
public List<Account> getAccountList(@Param("orderBy") String orderBy, @Param("orderRule") String orderRule,
@Param("start) int start, @Param("offset") int offset);

观察mybatis日志输出:

==>  Preparing: select * from account order by login_name DESC limit ?, ?
==> Parameters: 0(Integer), 50(Integer)

此时,对于使用${}格式引用的参数,mybatis直接在SQL语句中插入一个不改变的字符串,而不再作为一个预编译参数处理。

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

总结

如果只是想直接在SQL语句中插入一个不改变的字符串,比如,像ORDER BY,可以使用${}引用参数:ORDER BY ${columnName},这里mybatis不会修改或转义字符串。

mybatis字符串转义问题的更多相关文章

  1. 是否采用Sybase形式的自动字符串转义(用 '' 表示 ')

    ;; 关于php.ini ;; ; 这个文件必须命名为'php.ini'并放置在httpd.conf中PHPINIDir指令指定的目录中. ; 最新版本的php.ini可以在下面两个位置查看: ; h ...

  2. python字符串转义与正则表达式特殊字符转义

    最近在自学python,字符串和正则表达式的特殊字符转义有点混淆,做个笔记简单总结一下. 1.普通字符串转义 在字符串中使用特殊字符时,要用反斜杠(\)转义字符.例如:'Let\'s go!',这里对 ...

  3. PHP字符串转义

    与PHP字符串转义相关的配置和函数如下: 1.magic_quotes_runtime 2.magic_quotes_gpc 3.addslashes()和stripslashes() 4.mysql ...

  4. 从 RegExp 构造器看 JS 字符串转义设计

    多年前我第一次入职腾讯的时候,DC 从杭州给我寄来了一本他刚翻译出炉的<高性能 JavaScript>.那段时间为了帮忙校对,我仔细阅读了书中的每一个段落,结果积累了不少 JavaScri ...

  5. java字符串转义,把&lt;&gt;转换成<>等字符【原】

    java字符串转义,把<>转换成<>等字符 使用的是commons-lang3-3.4 中的StringEscapeUtils类 package test; import ja ...

  6. mybatis字符串模糊匹配

    1.  参数中直接加入%%,注意不需要加两个单引号,加了就会出错,因为系统会自动为字符串类型加上两个单引号 <select id="selectPersons" result ...

  7. MyBatis特殊字符转义

    使用mybatis的时候,特殊字符,例如<,>,<>,..... 需使用以下进行转义 < < 小于号 > > 大于号 & & 与 &am ...

  8. 字符串转义为HTML

    有时候后台返回的数据中有字符串,并需要将字符串转化为HTML,下面封装了一个方法,如下 // html转义 function htmlspecialchars_decode(string, quote ...

  9. react将字符串转义成html语句

    在使用reactjs库的时候,会遇到将一段html的字符串,然后要将它插入页面中以html的形式展现,然而直接插入的话页面显示的就是这段字符串,而不会进行转义,可以用以下方法插入,便可以html的形式 ...

随机推荐

  1. kubernetes 基础命令及操作

    获取集群的基本信息kubectl cluster-infokubectl get nodeskubectl get namespaceskubectl get deployment --all-nam ...

  2. BZOJ4695 最假女选手(势能线段树)

    BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...

  3. Leetcode 80.删除排序数组中的重复项 II By Python

    给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素最多出现两次,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例 ...

  4. X-PACK详解

    启用和禁用启用和禁用X-Pack功能默认情况下,所有X-Pack功能都被启用.您可以启用或禁用特定的X-Pack功能elasticsearch.yml,kibana.yml以及logstash.yml ...

  5. nginx.conf(centos6, 1.12)主配置文件修改

    #nginx1.12 centos6.xuser admin admin;worker_processes 4; error_log /data/services/logs/nginx_error.l ...

  6. [NOI2014]购票(斜率优化+线段树)

    题目描述 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会. 全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的父亲用道路连接 ...

  7. centos7安装mha4mysql

    mysql搭建mha需要用的两个rpm包.(manager包和node包) 下载地址:https://download.csdn.net/download/dajdajdajdaj/10603389 ...

  8. Python3 与 C# 并发编程之~进程先导篇

      在线预览:http://github.lesschina.com/python/base/concurrency/1.并发编程-进程先导篇.html Python3 与 C# 并发编程之- 进程篇 ...

  9. JQuery未来元素事件监听写法

    $(document).on('click','.div1',function(){ alert("abc"); }); 格式一致,第一个参数写事件,第二个参数给谁写事件(选择器) ...

  10. 【LOJ6284】数列分块8

    题目大意:维护一个序列,支持区间染色,查询区间中等于某个颜色的点的个数. 题解:考虑直接用线段树进行维护,维护区间相同颜色值和一个区间颜色是否相同的标记即可. 代码如下 #include <bi ...