MyBatis中SQL使用Order By 失效问题

2,446 阅读1分钟

这个Bug困扰了我好久好久... 我需要从前端传入orderBy 和 orderWay 两个参数进行排序,在sql语句中使用 #{orderWay}和#{orderWay},但是测试之后发现排序根本不起作用,在网上搜了很久,终于发现了原因(时间久主要是我搜问题没有搜准确,网上讲解的还是挺多的)

order by 后面要用${}

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

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

<if test="orderBy != null and orderWay != null">
    ORDER BY ${orderBy} ${orderWay}
</if>

但是 #方式能够很大程度防止sql注入。$方式无法防止Sql注入。

方式一般用于传入数据库对象,例如传入表名。一般能用#的就别用

所以order by 之后要使用$而非#。

#{} 可以防止SQL注入的原因

#{}有预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。SQL注入都是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。

使用PageHepler

PageHelper的order by方法,能替代mybatis中order by必须使用${}来避免sql注入

思路:com.github.pageHelper包里的orderBy方法来避免使用${},防止sql注入。

使用方法:在mapper的sql语言执行前,先执行PageHelper.orderBy(String string),比如:
String string="id"+" asc";
PageHelper.orderBy(string)
然后再去调取mapper的方法; 如果还有分页,可以调用
PageHelper.startPage(int pageNum,int PageSize, String orderBy)方法来结合分页排序进行操作。

www.jb51.net/article/201…
blog.csdn.net/m0_57640408…