mybatis字符串转义问题
问题描述
@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不会修改或转义字符串。
最新文章
- Windows错误码解析
- 简单快捷好用的vim配置和终端配置推荐
- 关于hql一些不常见但好用的技巧(个人总结)
- git clone 错误ca-certificates.crt
- CocoaPods的使用
- android 之 桌面的小控件AppWidget
- C# 3.0 扩展方法[转载]
- 下载文件的一种简单方法js
- nape.dynamics.InteractionFilter
- 【SSH2(实用文章)】--Struts2文件上传和下载的例子
- 【JavaWeb】权限管理系统
- Hive导入HDFS/本地数据
- Servlet和Filter生命周期
- [Swift]LeetCode433. 最小基因变化 | Minimum Genetic Mutation
- Jenkins 无法捕获构建脚本错误问题
- delphi property read writer 如何使用
- bzoj 4008 亚瑟王 - 动态规划 - 概率与期望
- ASP.NET MVC:@helper 不能调试
- iOS应用之间的跳转
- ASP.NET 中整合JavaScript的技巧