问题描述

@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. Hdoj 2188.悼念512汶川大地震遇难同胞——选拔志愿者 题解

    Problem Description 对于四川同胞遭受的灾难,全国人民纷纷伸出援助之手,几乎每个省市都派出了大量的救援人员,这其中包括抢险救灾的武警部队,治疗和防疫的医护人员,以及进行心理疏导的心理 ...

  2. Hdoj 1248.寒冰王座 题解

    Problem Description 不死族的巫妖王发工资拉,死亡骑士拿到一张N元的钞票(记住,只有一张钞票),为了防止自己在战斗中频繁的死掉,他决定给自己买一些道具,于是他来到了地精商店前. 死亡 ...

  3. edit 控件之隐藏光标

    @2019-02-22 [小记] 禁止聚焦功能便可实现

  4. NOIp2018 复习笔记

    其实也没什么用啦,只是来占个坑 OI知识 3367 [模板]并查集 就这么做啊 没什么其他的 就是可以做tarjan LCA和Kruskal的操作 //关键函数 int getfa(int t) { ...

  5. centos7使用yum安装zabbix3.4

     应用环境: 关于ZABBIX: zabbix一开强大的开源监控工具,同类型还有nagios,ganglia,cacti等监控工具,通过过去一年Google趋势就知道zabbix全球的相对热度:   ...

  6. 如何在jsp中引入bootstrap

    如何在jsp中引入bootstrap包: 1.首先在http://getbootstrap.com/上下载Bootstrap的最新版. 您会看到两个按钮: Download Bootstrap:下载 ...

  7. InnoDB,5项最佳实践,知其所以然?

    InnoDB,5项最佳实践,知其所以然? 原创: 58沈剑 架构师之路 昨天 缓存讲了一个月<缓存架构,一篇足够>.今天,开始写数据库. 第一篇,说说MySQL两个最常用的存储引擎,MyI ...

  8. goroutine与调度器

    29 November 2013 by skoo 我们都知道Go语言是原生支持语言级并发的,这个并发的最小逻辑单元就是goroutine.goroutine就是Go语言提供的一种用户态线程,当然这种用 ...

  9. 【CF375D】Tree and Queries

    题目大意:给定一棵 N 个节点的有根树,1 号节点为根节点,每个节点有一个颜色.有 M 个询问,每次询问以 i 为根的子树中颜色大于等于 K 的有多少种. 题解:子树询问直接 dfs 序转化成序列问题 ...

  10. django的RestFramework模块的源码分析

    一.APIView源码分析 查看源码的前提要知道,找函数方法必须先在自己的类中找,没有再往父类找,一层一层网上找,不能直接按ctrl点击 在我们自己定义的类中没有as_view方法的函数,所以肯定是继 ...