• 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不会修改或转义字符串。

  • 相关阅读:
    java虚拟机字节码执行引擎
    java7 invokedynamic命令深入研究
    [转载]使用expect实现shell自动交互
    elasticsearch 聚合时 类型转换错误
    ES的关键端口
    CentOS6.5安装ganglia3.6
    Linux远程执行echo问题
    [转载]CentOS修改用户最大进程数
    elasticsearch新加入节点不能识别问题
    ssh免密码登录的注意事项
  • 原文地址:https://www.cnblogs.com/nuccch/p/7867988.html
Copyright © 2020-2023  润新知