概述
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注入
2. $传参
$ 方式会传入一个不改变的字符串,不能够防止注入
如:order by #{orderBy},如果传入的时间是 ,则会被解析为 order by update_time
因此,能用#号就别用$。
有的需求难免会需要我们动态传入表名,排序字段和方式这样的情况,不能使用#号传参了,使用$传参又希望能够防止注入保证安全。下面介绍一下我的解决方式。
二、$传参如何防止注入
使用枚举的方式可以解决这个问题,简单的说就是提前定义好我们的表名、排序字段和排序方式有哪些。将我们需要用到的表名、排序字段和排序方式这些内容定义到单独的枚举类或者常量定义类中。
下面介绍两种方式:
2.1 在业务代码中判断防止注入:
在业务代码中进行判断,不在此范围的我就直接按默认方式处理,这样就可以过滤掉不规范的参数和sql的注入代码。
关键代码:
仅以开始时间和更新时间的排序介绍,可根据实际需求的情况添加其他业务字段,
// 默认开始时间倒序
param.setOrderBy("begin_time");
param.setSort("DESC");
if (StringUtils.isNotEmpty(param.getOrderBy())) {
switch (param.getOrderBy()) {
case "updateTime":
param.setOrderBy("update_time");
break;
default:
param.setOrderBy("begin_time");
}
}
// 如果是升序,就重新设置为升序
if("ascending".equals(param.getSort())) {
param.setSort("ASC");
}
处理过后都是我们可控的属性内容,就可以直接使用$传参了,如:
SELECT <include refid="Base_Column_List"/>
FROM alarm_list_info_view as m
<where>
m.status = 0
</where>
order by ${param.orderBy} ${param.sort}
2.1 在mybatis的xml文件中判断枚举防注入
关键代码:
SELECT <include refid="Base_Column_List"/>
FROM alarm_list_info_view as m
<where>
<if test="param.orderBy== 'begin_time'">
order by begin_time
</if>
<if test="param.orderBy== 'update_time'">
order by update_time
</if>
</where>
// 或者这样 总之先保证是我们需要的排序字段和方式 一般字段也不会太多 不够可以添加
SELECT * FROM alarm_list_info_view as m
<choose>
<when test="(orderBy=='begin_time' or orderBy=='update_time') and (sort=='desc' or sort=='asc')">
order by ${orderBy} ${sort}
</when>
<otherwise>
order by updateTime desc
</otherwise>
</choose>
按照这个思路就能完美解决了,各位大佬有别的解法请求指教。
最后
以上就是彪壮音响为你收集整理的mybatis动态传入order by(排序字段) 和 sort(排序方式) 防止注入的全部内容,希望文章能够帮你解决mybatis动态传入order by(排序字段) 和 sort(排序方式) 防止注入所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复