jeecgboot mapper.xml联合查询之前端灵活使用表别名筛选
# jeecgboot mapper.xml联合查询之前端灵活使用表别名筛选
一、背景
一个项目使用jeecgboot来进行开发,有一个需求:报表里的关键字段都能在前端做查询筛选。由于这个报表是通过mapper.xml 里写sql然后动态拼接的,很多关键字段在不同的表里,如果前端直接传name=xxx,将会报错:Column 'name' in where clause is ambiguous
,大概意思是表字段不明确。又或者我只想查老师级别level=1下的学生时,直接传level=1,也同样会报错。
-- 这个是举例说明,实际业务比这复杂得多
select a.name,b.sex,c.name,c.level tName from students a
left join sexs b on a.sexId=b.sexId
inner join teachers c on a.tId=c.id
${ew.customSqlSegment}
二、分析
解决思路比较简单,要确保${ew.customSqlSegment}
里拼接的where条件,带上对应的别名。但jeecgboot默认不支持传别名字段,怎么办呢?经过分析前后端源码,解决步骤大概如下:
- 重写getQueryParams
前端重写getQueryParams,var params = this.getQueryParams()
在params参数里对需要明确别名的字段加上别名。 后端改queryWrapper
在
QueryGenerator---installMplus
里增加对别名字段的处理,让它拼接成需要的where查询。
三、具体代码
前端
==注意必须delete ,否则旧的参数也会提交过去,导致后端没法明确字段而报错==
getQueryParams(){//重写查询 。。。。。。。 var params= filterObj(param); if(params.level) { params['c.level']=params.level delete params.level } if(params.name){ params['c.name']=params.name delete params.name } return params; }
后端
在QueryGenerator的installMplus
里增加。注意是在else里加上,因为比如要查level,前端传来c.level,在searchObj里不存在(==level=null==),所以不会去查值,导致value必然为null。然后对过request中的parameterMap判断是否有带别名的字段,去掉别名后如果与当前字段相同,则认为需要手动加别名。将原来的key换成新别名。column=key
并将查询内容赋值给value=String.join(",",parameterMap.get(key));
public static void installMplus(QueryWrapper<?> queryWrapper, Object searchObj, Map<String, String[]> parameterMap) { 。。。。。 if (null != value && value.toString().startsWith(COMMA) && value.toString().endsWith(COMMA)) { 。。。。。。 }else { //如果值为空,有可能是前端给了别名,此时应该去别名后再匹配实体字段,相同则从reqMap里取值。 if(null==value && parameterMap!=null){ String finalColumn = column; String key= parameterMap.keySet().stream().filter(x->( x.contains(".") && x.contains(finalColumn))).findFirst().orElse(null); if(key!=null){ column=key; //这里是前端传来的要查询的内容 ['xx','xxx2'] value=String.join(",",parameterMap.get(key)); } } //根据参数值带什么关键字符串判断走什么类型的查询 QueryRuleEnum rule = convert2Rule(value); 。。。。。 } }
当然,上面的判断其实是不严谨的,可以自己想办法增强!
评论已关闭