这个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)方法来结合分页排序进行操作。