循环递归递归查询树的下级树
整体思路是查询所有树节点,根据父树节点id循环树节点组装一个map,key为树父节点id, @Override public List<Integer> queryChildOrganizationStatusByIdList(List<Integer> organizationIds) throws Exception { List<Integer> orgIdList = null; // 返树对象集合. Map<Integer, Map<String, Object>> returnMap = new HashMap<Integer, Map<String, Object>>(); // 查询所树节点集合. List<Map<String, Object>> list = itsmSystemOrganizationMapper.selectOrdinaryOrganization(); //封装组织集合对象, [键值对]→[组织id == 组织id,名称,parentId] Map<Integer, Map<String, Object>> idMap = new HashMap<Integer, Map<String, Object>>(list.size()); // 获取封装集合对象的key,所有的节点id. for (int i = 0, size = list.size(); i < size; i++) { idMap.put((Integer) list.get(i).get(MapConstant.ID), list.get(i)); } if (organizationIds == null && organizationIds.size() <= 0) { returnMap.putAll(idMap); } // 循环递归获取当前节点的子节点(递归). for (Integer organizationId : organizationIds) { child(list, organizationId, idMap, returnMap); returnMap.putAll(returnMap); } if (organizationIds != null && organizationIds.size() > 0) { orgIdList = new ArrayList<Integer>(); for (Map.Entry<Integer, Map<String, Object>> entry : returnMap.entrySet()) { orgIdList.add(entry.getKey()); } } return orgIdList; } /** * 根据节点id查询父节点、子节点、当前节点的id name. * <p> * <br>��author chengyuebin */ @Override public Map<Integer, Map<String, Object>> queryParentAndChild(Integer id) throws Exception { // 最终返回的数据. Map<Integer, Map<String, Object>> returnMap = new HashMap<Integer, Map<String, Object>>(); // 数据库所有数据Map. List<Map<String, Object>> list = itsmSystemOrganizationMapper.selectIdAndNameAndParentIdAll(); // 新的Map. key - 主键id, value - id,name,parentId. Map<Integer, Map<String, Object>> idMap = new HashMap<Integer, Map<String, Object>>(list.size()); // 转换数据格式. Map<String, Object> map = null; for (int i = 0, size = list.size(); i < size; i++) { idMap.put((Integer) list.get(i).get("id"), list.get(i)); } if (id == null) { return idMap; } // 找到当前记录. Map<String, Object> current = idMap.get(id); // 当前节点的父节点. // Integer parentId = (Integer) current.get("parentId"); // 当前节点的父节点(递归). // while (0 != parentId.intValue()) { // if(idMap.containsKey(parentId)) { // returnMap.put(parentId, idMap.get(parentId)); // // parentId = (Integer) idMap.get(parentId).get("parentId"); // } // } // Integer parentId = (Integer) current.get("parentId"); //获得当前节点 // // while (0 != id.intValue()) { // if(idMap.containsKey(parentId)) { // returnMap.put(parentId, idMap.get(parentId)); // // parentId = (Integer) idMap.get(parentId).get("parentId"); // } // } // 当前节点的子节点(递归). child(list, id, idMap, returnMap); return returnMap; } /** * 查询出所有的数据 * <p> * <br>��param: * <br>��return: */ @Override public ItsmSystemOrganizationResult queryOrganizationAll() { ItsmSystemOrganizationResult result = new ItsmSystemOrganizationResult(); List<ItsmSystemOrganizationBean> list = itsmSystemOrganizationMapper.queryOrganizationAll(); @SuppressWarnings("unchecked") Map<Integer, List<ItsmSystemOrganizationBean>> areaMap = new HashedMap(); if (areaMap == null) { return null; } for (ItsmSystemOrganizationBean areaBean : list) { if (!areaMap.containsKey(areaBean.getParentId())) { areaMap.put(areaBean.getParentId(), new ArrayList<ItsmSystemOrganizationBean>()); } areaMap.get(areaBean.getParentId()).add(areaBean); } //封装一级对象 List<ItsmSystemOrganizationBean> itemCatList1 = areaMap.get(0); getListOrganization(result, areaMap, itemCatList1); return result; } public void getListOrganization(ItsmSystemOrganizationResult result, Map<Integer, List<ItsmSystemOrganizationBean>> areaMap, List<ItsmSystemOrganizationBean> itemCatList1) { for (ItsmSystemOrganizationBean itsmSystemOrganizationBean : itemCatList1) { ItsmSystemOrganizationData itemCatData = new ItsmSystemOrganizationData(); itemCatData.setId(itsmSystemOrganizationBean.getId()); itemCatData.setParentId(itsmSystemOrganizationBean.getParentId()); itemCatData.setParentFlag(itsmSystemOrganizationBean.isParentFlag()); itemCatData.setOrganizationCode(itsmSystemOrganizationBean.getOrganizationCode()); itemCatData.setOrganizationName(itsmSystemOrganizationBean.getOrganizationName()); itemCatData.setDescription(itsmSystemOrganizationBean.getDescription()); itemCatData.setOpenFlag(itsmSystemOrganizationBean.getOpenFlag()); result.getSystemOrganizationBeans().add(itemCatData); if (itsmSystemOrganizationBean.isParentFlag()) { continue; } //封装其他的节点 getList(areaMap, itsmSystemOrganizationBean.getId(), itemCatData); } } public void getList(Map<Integer, List<ItsmSystemOrganizationBean>> areaMap, Integer id, ItsmSystemOrganizationData itemCatData) { //封装二级 List<ItsmSystemOrganizationBean> itemCatList2 = areaMap.get(id); List<ItsmSystemOrganizationData> itemCatData2 = new ArrayList<ItsmSystemOrganizationData>(); itemCatData.setItems(itemCatData2); if (itemCatList2 == null) { return; } for (ItsmSystemOrganizationBean itemCat2 : itemCatList2) { ItsmSystemOrganizationData id2 = new ItsmSystemOrganizationData(); id2.setId(itemCat2.getId()); id2.setOrganizationName(itemCat2.getOrganizationName()); id2.setOrganizationCode(itemCat2.getOrganizationCode()); id2.setParentFlag(itemCat2.isParentFlag()); id2.setParentId(itemCat2.getParentId()); id2.setDescription(itemCat2.getDescription()); id2.setOpenFlag(itemCat2.getOpenFlag()); itemCatData2.add(id2); if (!itemCat2.isParentFlag()) { System.out.println(areaMap + "======" + itemCat2 + "=====" + id2); getList(areaMap, itemCat2.getId(), id2); } else { continue; } } } /** * 获取节点的子节点. * <p> * <br>��param: list 数据库所有数据Map. * <br>��param: currentId 当前节点Id. * <br>��param: idMap 新的Map. key - 主键id, value - id,name,parentId. * <br>��param: returnMap 返回的数据. * * @throws Exception */ private void child(List<Map<String, Object>> list, Integer currentId, Map<Integer, Map<String, Object>> idMap, Map<Integer, Map<String, Object>> returnMap) throws Exception { // 将当前节点的数据添加到返回数据. returnMap.put(currentId, idMap.get(currentId)); List<Integer> currentChildIdList = new ArrayList<Integer>(); for (int i = 0, size = list.size(); i < size; i++) { // 记录当前节点的子节点. Integer parentId = (Integer) list.get(i).get(MapConstant.PARENTID); if (null != parentId && currentId.intValue() == parentId.intValue()) { // 当前节点的子节点. Integer currentChildId = (Integer) list.get(i).get(MapConstant.ID); currentChildIdList.add(currentChildId); // 将当前节点的子节点数据添加到返回数据. returnMap.put(currentChildId, idMap.get(currentChildId)); child(list, currentChildId, idMap, returnMap); } } }
递归排序:
数据结构:
public class ItsmSystemResourceData { /** * 主键id */ private Integer id; /** * 父资源id */ private String parentResourceId; /** * 资源名称 */ private String resourceName; /** * 资源url */ private String resourceUrl; /** * 资源描述 */ private String description; /** * 资源类型 0:功能 1:按钮 */ private int resourceType; /** * 资源排序号 */ private int resourceSort; /** * 资源可操作权限 0:查询 1:新增 2:更新 3:删除 */ private int operatingAuthorization; /** * 是否父节点[1 true 有子集 0false] */ private boolean parentFlag; /** * 对开发人员可见 */ private boolean visible; @JsonProperty("children") private List<?> items;
定义返回结果集:
public class ItsmSystemResourceResult { //指定json序列化后的名称 叫data @JsonProperty("top") private List<ItsmSystemResourceData> resourceDataList = new ArrayList<>(); public List<ItsmSystemResourceData> getResourceDataList() { return resourceDataList; } public void setResourceDataList(List<ItsmSystemResourceData> resourceDataList) { this.resourceDataList = resourceDataList; }
}
菜单树工具类:
public class TreeUtil { private int count = 0; private List<ItsmSystemResourceData> nodes; public TreeUtil(List<ItsmSystemResourceData> nodes){ this.nodes = nodes; } public List<ItsmSystemResourceData> buildTree(){ List<ItsmSystemResourceData> list = new ArrayList<ItsmSystemResourceData>(); for (ItsmSystemResourceData node : nodes) { if (node.getParentResourceId().equals("0")) { list.add(node); } } list = getSortChildren(list); for (ItsmSystemResourceData node : list) { build(node); } return list; } /*** * 构建权限树 * @Title: build * @Description: TODO * @param node */ private void build(ItsmSystemResourceData node){ List<ItsmSystemResourceData> children = getChildren(node); if (!children.isEmpty()) { node.setItems(children); if(count <3){ //children.get(0).setChecked("true");//设置默认选中 count ++; } for (ItsmSystemResourceData child : children) { build(child); } } } /** * * @Title: getChildren * @Description: TODO 获取子节点 * @param node * @return */ private List<ItsmSystemResourceData> getChildren(ItsmSystemResourceData node){ List<ItsmSystemResourceData> children = new ArrayList<ItsmSystemResourceData>(); String id = String.valueOf(node.getId()); for (ItsmSystemResourceData child : nodes) { if (id.equals(child.getParentResourceId())) { children.add(child); } } return getSortChildren(children); // return children; } /** * * @Title: getChildren * @Description: TODO 获取排序子节点 * @param children * @return */ private List<ItsmSystemResourceData> getSortChildren(List<ItsmSystemResourceData> children){ MyCompare my = new MyCompare(); Collections.sort(children,my) ; return children; } /** * * @Title: getChildren * @Description: TODO 获取排序子节点 * @param children * @return */ public static List<ItsmSystemResourceData> getSortList(List<ItsmSystemResourceData> children){ MyCompare my = new MyCompare(); Collections.sort(children,my) ; return children; } }
工具类中使用的比较器
/** * 比较器 */ public class MyCompare implements Comparator<ItsmSystemResourceData> { @Override public int compare(ItsmSystemResourceData o1, ItsmSystemResourceData o2) { if (o1.getResourceSort() < o2.getResourceSort()) { return -1; } else { return 1; } } }
递归查询所有的菜单资源
public ItsmSystemResourceResult queryResourceByAll(UserLoginInfo info) { //一次查询所有资源,状态为0的 List<ItsmSystemResourceBean> resourceBeanList = new ArrayList<ItsmSystemResourceBean>(); if (!info.getId().equals(this.developer)) { //不是开发人员根据父资源id归类查询数据未删除的不包括隐藏的 resourceBeanList = resourceMapper.selectResourceByUnDelete(); }else {//开发人员根据父资源id归类查询数据未删除和隐藏的 resourceBeanList = resourceMapper.selectResourceByAll(); } Map<String, List<ItsmSystemResourceBean>> map = getStringListMap(resourceBeanList); //定义返回对象 ItsmSystemResourceResult itsmSystemResourceResult = new ItsmSystemResourceResult(); //根据父资源id递归封装下级的资源对象组装成返回数据 getFirstrderDataResource(itsmSystemResourceResult, map); //获取菜单树下节点 List<ItsmSystemResourceData> resourceDataList = itsmSystemResourceResult.getResourceDataList(); //调用菜单树工具类排序 TreeUtil tree = new TreeUtil(resourceDataList); //返回按照sortid排好序的树形结构的菜单 List<ItsmSystemResourceData> datalist = tree.buildTree(); ItsmSystemResourceResult resourceResult = new ItsmSystemResourceResult(); resourceResult.setResourceDataList(datalist); return resourceResult; }
/** * 根据资源的顶级父资源id=0 封装一级返回数据 * * @param itsmSystemResourceResult * @param map */ private void getFirstrderDataResource(ItsmSystemResourceResult itsmSystemResourceResult, Map<String, List<ItsmSystemResourceBean>> map) { //从封装的第一级数据firstOrderData从顶级节点开始 //1 从0级开始,获取顶级父节点组装数据 List<ItsmSystemResourceBean> firstOrderData = map.get("0"); //2循环顶级父节点组装的数据设置返回数据对象 for (ItsmSystemResourceBean resourceBean : firstOrderData) { ItsmSystemResourceData itsmSystemResourceData = new ItsmSystemResourceData(); //3copy资源对象属性到返回数据对象中 BeanUtils.copyProperties(resourceBean, itsmSystemResourceData); //设置递归返回结果集的元素 itsmSystemResourceResult.getResourceDataList().add(itsmSystemResourceData); if (!resourceBean.isParentFlag()) {//当前循环节点如果不是父节点,结束此节点循环,不封装其他级 continue; } //2是父节点封装其他级数据firstOrderData getSubordinateDataResource(resourceBean.getId(), itsmSystemResourceData, map); } }
/** * 根据父节点下的id封装其他级数据 * * @param id * @param itsmSystemResourceData * @param map */ private void getSubordinateDataResource(Integer id, ItsmSystemResourceData itsmSystemResourceData, Map<String, List<ItsmSystemResourceBean>> map) { //获取其他父节点下的封装数据 List<ItsmSystemResourceBean> resourceBeanList = map.get(String.valueOf(id)); //定义返回数据对象 List<ItsmSystemResourceData> resourceDataList = new ArrayList<>(); itsmSystemResourceData.setItems(resourceDataList); if (resourceBeanList == null) {//当前层级为空直接返回不进行递归 return; } //循环当前层级数据 for (ItsmSystemResourceBean bean : resourceBeanList) { ItsmSystemResourceData resourceData = new ItsmSystemResourceData(); //复制资源数据到返回数据对象bean BeanUtils.copyProperties(bean, resourceData); //返回数据增加数据 resourceDataList.add(resourceData); if (!bean.isParentFlag()) {//不是父节点结束此节点循环不递归组装 continue; } else {//是父节点继续调用递归 getSubordinateDataResource(bean.getId(), resourceData, map); } } } }
性能消耗小
<!--根据id查询用户[不包括离职禁用]--> <select id="selectOrdinaryUserByIds" resultType="com.ahies.itsm.system.sso.pojo.ItsmSystemUserBean"> <foreach collection="userIdList" item="id" open="" close="" separator="UNION"> SELECT * FROM itsm_sys_user a WHERE a.id = #{id} and a.status = 0 and a.available_status=0 and a.account_status=0 </foreach> </select>
消耗性能da
<select id="queryUserByIds" resultType="com.ahies.itsm.system.sso.pojo.ItsmSystemUserBean"> SELECT * FROM itsm_sys_user WHERE status = 0 and id IN <foreach collection="ids" index="index" item="id" open="(" separator="," close=")"> #{id} </foreach> </select>