搜索过滤树结构
搜索过滤树结构
基本思路:
-
搜索过滤一般是多字段查询过滤,先利用wrapper获取查询到的所有叶子节点
- 搜索一般为名称模糊查询
- 过滤有可能单选、多选和区间过滤
- 故所搜过滤一般wrapper包装类查询,即QueryWrapper
- 可利用wrapper中的四种查询语句以满足搜索过滤的需求:like(模糊查询)、eq(等于)、in(在...之内)、between(区间查询)
-
再利用叶子节点获取树结构
- 例用递归查询出所有的节点(从叶子节点一直递归到根节点),保留所有节点id,idSet
- 查询出所有根节点,保留所有根节点整条信息,并保留根节点之间的顺序(顺序也是树结构的一部分),rootList
-
构建搜索过滤树的层级结构
- 从查询出的根节点出发,rootList走foreach循环每一个根节点
- 首先获取根节点的子,再与idSet求交,交集即为所求树中实际的子,求交时要注意取子的交,因为子中保留了顺序,顺序也是树结构的一部分
- 再对每一个子递归,一直到无子的叶子节点
//搜索过滤树结构 public List<T> getWrapper(Map<String, Object> param) { QueryWrapper<T> wrapper = new QueryWrapper<>(); String key = "name"; String value = StringKit.of(param.get(key)); if (!value.isEmpty()) { wrapper.like("name", value);//like条件 } key = "test_id"; value = StringKit.of(param.get(key)); if (value.isEmpty()) { return null; } wrapper.eq(key, where);//eq条件 key = "result"; if (param.containsKey(key)) { value = StringKit.of(param.get(key)); if (value.isEmpty()) { return null; } String[] resultArray = where.split(","); List<Object> resultList = new ArrayList<>(); for (String re : resultArray) { if (StringKit.notEmpty(re)) { resultList.add(StringKit.of(re)); } } if (resultList.isEmpty()) { return null; } wrapper.in(key, resultList);//in条件 } wrapper.eq("dir", false);//加上非文件夹条件 //获取wrapper查询出的叶子节点 List<T> tList = mapper.selectList(wrapper); //准备idSet,用于存放所有的节点id Set<Long> idSet = new HashSet<>(); //准备rootList,用于存方法根节点 List<T> rootList = new ArrayList<>(); //先判断查询出的叶子列表是否为空 if(tList.size() == 0) { return new ArrayList<>(); }else { //把叶子节点id加入idSet tList.forEach(t -> idSet.add(t.getId())); //把叶子节点的所有父节点加入idSet,把根节点加入根集合 tList.forEach(t -> getParentIdsById(t,idSet,rootList)); //对根集合每个元素插入与idSet中相交的子 rootList.forEach(r -> setChildrenByIdSet(r,idSet)); return rootList; } } //递归,获取获取所有父节点id的set集合,并且获取根节点的list集合 private void getParentIdsById(T t,Set<Long> idSet,List<T> rootList){ Long parentId = t.getParent_id(); //根节点加入根集合 if(parentId == 0L) { //根集合为了保证顺序故使用list,故应加去重判断 if(!rootList.contains(t)) rootList.add(t); }else { //非根节点的id加入idSet T parent = getById(parentId); if(parent != null) { idSet.add(parentId); //递归 getParentIdsById(parent,idSet,rootList); } } } //递归,把idSet与childrenIdList的交集设置为parent的子 private void setChildrenByIdSet(T parent,Set<Long> idSet) { //获取子节点id的集合 List<Long> childrenIdList = mapper.selectIdsByParent(parent.getId()); //此为递归判断条件 if(childrenIdList.size() > 0) { //取交,带有顺序的list放前面,取交后的集合也保持顺序 childrenIdList.retainAll(idSet); //对交集实例化 List<T> children = mapper.selectBatchIds(childrenIdList); //递归子节点 children.forEach(c -> setChildrenByIdSet(c,idSet)); //设值为子 parent.set_children(children); } }
- 从查询出的根节点出发,rootList走foreach循环每一个根节点