
mybatis动态传入order by(排序字段) 和 sort(排序方式) 只能使用KaTeX parse error: Expected 'EOF', got '#' at position 8: {}传参方式,#̲{}传参无效。但众所周知使用{}传参会有SQL注入问题,上网查了一下很多都说鱼与熊掌不可兼得,接下来介绍一下如何使用动态传参且能够防止注入的方法。
一、mybatis的两种传参方式#{}和${} 1. #传参1.1 # 是通过prepareStatement的预编译的,会对自动传入的数据加一个单引号。
如:order by #{orderBy},如果传入的时间是 ,则会被解析为 order by ‘update_time’ (这样排序是无效的,这也是为什么不能用#号传参的原因)。
1.2 #方式能够很大程度防止sql注入
$ 方式会传入一个不改变的字符串,不能够防止注入
如:order by #{orderBy},如果传入的时间是 ,则会被解析为 order by update_time
因此,能用#号就别用$。
有的需求难免会需要我们动态传入表名,排序字段和方式这样的情况,不能使用#号传参了,使用$传参又希望能够防止注入保证安全。下面介绍一下我的解决方式。
使用枚举的方式可以解决这个问题,简单的说就是提前定义好我们的表名、排序字段和排序方式有哪些。将我们需要用到的表名、排序字段和排序方式这些内容定义到单独的枚举类或者常量定义类中。
下面介绍两种方式:
在业务代码中进行判断,不在此范围的我就直接按默认方式处理,这样就可以过滤掉不规范的参数和sql的注入代码。
关键代码:
仅以开始时间和更新时间的排序介绍,可根据实际需求的情况添加其他业务字段,
// 默认开始时间倒序
if (StringUtils.isNotEmpty(param.getOrderBy())) {
switch (param.getOrderBy()) {
case "updateTime":
param.setOrderBy("update_time");
break;
default:
param.setOrderBy("begin_time");
}
} else {
param.setOrderBy("begin_time");
}
if(StringUtils.isNotEmpty(param.getSort()) && param.getSort().equals("ascending")) {
param.setSort("ASC");
} else {
param.setSort("DESC"); // 默认时间倒序
}
处理过后都是我们可控的属性内容,就可以直接使用$传参了,如:
SELECT2.1 在mybatis的xml文件中判断枚举防注入FROM alarm_list_info_view as m m.status = 0 order by ${param.orderBy} ${param.sort}
关键代码:
SELECtFROM alarm_list_info_view as m order by begin_time order by update_time
按照这个思路就能完美解决了,各位大佬有别的解法请求指教。