高级查询与注入原创
# 高级查询
# 概要
警告
高级查询中的列,系统暂时未对其控制,会导致数据敏感,后期会对列进行控制,只有后台配置的列才允许参与高级查询
为满足客户对业务的复杂条件查询,系统支持高级查询功能,高级查询是SQL的一种注入方式,即前端可以根据自身的查询需求来进行条件拼接,高级查询的组成为
- ”或“和”与“操作符,即多个条件间的连接符
- 列名 数据库表对应的列
- 条件 列名参与的条件
- 值 高级查询条件比对的值
# 规则
为保证数据的安全性,防止数据注入,对于高级查询制定了相应的规则
- 操作符 、列名、条件只能进行选择,无法进行录入
- 值进行了过滤,屏蔽了数据库相应的关键字及其符号,防止进行拼接注入
- 高级查询提交后会进行敏感字符过滤,并生成内置对象,再由内置对象进行处理,而不是直接生成SQL
# 列名
前端的高级查询已被封装为特定的组件,只有组件内定义的列名才能参与高级查询列的选择,为解决连表查询问题,列名支持 ”表名“."列名"的格式
# 条件
构建高级查询时,条件不允许输入,只允许选择,提交后会与后台允许的条件关键字进行匹配是否合法,系统提供的条件关键字为
- 模糊,即LIKE模糊匹配
- 等于 全部匹配
- 不等于 不相等匹配
- 大于 数值/日期类型大于匹配
- 大于等于 数值/日期类型大于或等于匹配
- 小于 数值/日期类型小于匹配
- 小于等于 数值/日期类型小于或等于匹配
- 包含 包含其中的某个的匹配(以逗号分割)
- 不包含 不包含其中的某个匹配(以逗号间隔)
# 注入支持
系统对高级查询做了注入支持,具体可参考如下步骤
- 高级查询会映射成List<com.baomibing.core.wrap.AdvanceSearchWrap>对象,因此在dto中青添加对应的属性
- 通过AdvanceSearchParser.toSQL方法转化为SQL字符串
- 通过SqlInjectContext.set方法进行SQL注入到对应的mapper方法中
- 在需要注入的服务实现类方法中添加@InjectSupport注解
对应的示例为
@InjectSupport
@override
public SearchResult<WmsOrder> search(WmsOrder dto, int pageNo, int pageSize) {
if (Checker.BeNotEmpty(dto.getAdvanceSearchWraps())) {
String sql = AdvanceSearchParser.toSQL(dto.getAdvanceSearchWraps());
SqlInjectContext.set("countOrder", sql);
SqlInjectContext.set("listOrder", sql);
}
return searchOrder(dto, pageNo, pageSize);
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
其中 countOrder和listOrder为对应的mapper方法,通过SqlInjectContext.set方法将mapper方法与注入的SQL进行绑定