多个子表VO 获取子表getChildren()方式

子表查询实践
本文介绍了一种通过主表获取子表数据的方法,使用getChildren方法结合特定子表类(FinProdInBodyVO.class)实现数据获取。此方法适用于拥有多个子表的复杂数据结构。

如果主表有多个子表 getChildren 可能会用到tableVO 通过tablecode。 查看源代码 可以通过子表class获取

FinProdInBodyVO[] finProdInBodyVOs = (FinProdInBodyVO[])finProdInVOs[0].getChildren(FinProdInBodyVO.class);
public Object dptCount(String deptId) { JSONObject res = new JSONObject(); String departmentId; if(StringUtil.isNullOrEmpty(deptId)){ departmentId = todoProcessReportMapper.getDeptIdByUserId(UserUtil.getCurrentUserId()); }else{ departmentId = deptId; } //获取对应部门ID的所有下级部门 List<TodoProcessingDptVo> subDepartments = getSubDepartments(departmentId); //获取所有的部门ID进行个人待办任务的统一查询 String deptIds = subDepartments.stream() .map(TodoProcessingDptVo::getDepartmentId) .collect(Collectors.joining(",")); TodoProcessingVo processingVo = new TodoProcessingVo(); processingVo.setDepartmentId(deptIds); processingVo.setIsDetails("0"); processingVo.setIsExport("1"); Object totalTodoReportList = getTotalTodoReportList(processingVo); JSONObject jsonObject = JSON.parseObject(totalTodoReportList.toString()); JSONArray list = jsonObject.getJSONArray("list"); //通过部门ID将个人待办进行按部门分组 Map<String,List<JSONObject>> deptMap = list.stream() .map(obj -> (JSONObject) obj) .collect(Collectors.groupingBy(jsonObj -> jsonObj.getString("departmentId"))); //根据个人待办数据统计部门待办数据 for (TodoProcessingDptVo subDepartment : subDepartments) { subDepartment.setCount(0); subDepartment.setOne(0); subDepartment.setOneAndThree(0); subDepartment.setMoreThree(0); subDepartment.setTotalExtension(0); subDepartment.setMaxExtensiveDay(0); List<JSONObject> todoList = deptMap.get(subDepartment.getDepartmentId()); if (todoList != null) { // 计算统计值 int count = 0; int one = 0; int oneAndThree = 0; int moreThree = 0; int totalExtension = 0; int maxExtensiveDay = 0; for (JSONObject obj : todoList) { count += Integer.parseInt(obj.getString("count")); one += Integer.parseInt(obj.getString("one")); oneAndThree += Integer.parseInt(obj.getString("oneAndThree")); moreThree += Integer.parseInt(obj.getString("moreThree")); totalExtension += Integer.parseInt(obj.getString("totalExtension")); int newMaxExtensiveDay = Integer.parseInt(obj.getString("maxExtensiveDay")); maxExtensiveDay = Math.max(maxExtensiveDay, newMaxExtensiveDay); } // 更新匹配的 subDepartment subDepartment.setCount(count); subDepartment.setOne(one); subDepartment.setOneAndThree(oneAndThree); subDepartment.setMoreThree(moreThree); subDepartment.setTotalExtension(totalExtension); subDepartment.setMaxExtensiveDay(maxExtensiveDay); } } //组装部门树结构 List<TodoProcessingDptVo> todoProcessingDptVos = buildDptTree(subDepartments); res.put("list",todoProcessingDptVos); return res; } /** * 获取对应部门ID的所有下级部门 * */ private List<TodoProcessingDptVo> getSubDepartments(String rootId) { List<TodoProcessingDptVo> allDepts = todoProcessReportMapper.getDptData(); Map<String, TodoProcessingDptVo> deptMap = allDepts.stream() .collect(Collectors.toMap(TodoProcessingDptVo::getDepartmentId, d -> d)); List<TodoProcessingDptVo> result = new ArrayList<>(); Deque<TodoProcessingDptVo> queue = new ArrayDeque<>(); TodoProcessingDptVo root = deptMap.get(rootId); if (root != null) { queue.add(root); } while (!queue.isEmpty()) { TodoProcessingDptVo current = queue.poll(); result.add(current); for (TodoProcessingDptVo dept : allDepts) { if (current.getDepartmentId().equals(dept.getParentId())) { queue.add(dept); } } } return result; } /** * 构建树结构方法 * * @param dptDataList */ private List<TodoProcessingDptVo> buildDptTree(List<TodoProcessingDptVo> dptDataList) { Map<String, TodoProcessingDptVo> nodeMap = new HashMap<>(); for (TodoProcessingDptVo vo : dptDataList) { vo.setChildren(new ArrayList<>()); nodeMap.put(vo.getDepartmentId(), vo); } List<TodoProcessingDptVo> rootList = new ArrayList<>(); for (TodoProcessingDptVo vo : dptDataList) { String parentId = vo.getParentId(); if (parentId == null || parentId.isEmpty() || !nodeMap.containsKey(parentId)) { rootList.add(vo); } else { TodoProcessingDptVo parent = nodeMap.get(parentId); parent.getChildren().add(vo); } } return rootList; } 像这里 我能不能再加一个逻辑就是返回的数据时,父部门要统计所有子部门的数据,相当于如果有:部门1,部门2,部门3,部门4四个部门 ,部门1有子部门:部门2和部门3,部门3有子部门:部门4,那么部门3要统计上自己本身有的数量,加上部门4
07-18
这个生成最终结构树的代码没有考虑到,如果是资源的情况,即当matchAll为true时。示全部资源。为false示首个资源。比如说现在的情况是有五个,相当于结构树会有五层。每一层都存放对应的数据,比如说机组层肯定是只有一个的,但是系统层可能会匹配到个系统。就是逻辑树他第二层系统层假如有一个节点,名称为燃煤系统。然后我们匹配资源的时候发现有两个1号燃煤系统和2号燃煤系统。这个时候最终的结构树的系统层就应该有两个节点来示这两个系统。因此判断条件也需要改一下,从原来的只使用名称来模糊查询还需要使用到id。比如说系统匹配资源,就使用逻辑树的系统名称加上机组id。然后其子节点中也需要加入id(因为现在是没有加入的),最后如果是全部资源,那么这两个系统都要加入,如果是首个,就只需要加一个。 public ActionResult getInstantiateTemp(@RequestBody BizAssetStructureTreePagination pagination) throws Exception { try { // 参数校验 if (pagination.getUnitId() == null || pagination.getIsAuto() == null || pagination.getMatchRule() == null) { return ActionResult.fail(MsgCode.VS009.get()); } // 1. 获取逻辑树结构 List<AssetStructureTreeNode> logicTree = bizAssetStructureTreeService.getOneTreeStructure("0", 1); if (logicTree == null || logicTree.isEmpty()) { return ActionResult.fail(MsgCode.MSERR122.get()); } List<AssetStructureTreeNode> builtTree = TreeBuilder.buildTree(logicTree); TreeBuilder.setLevels(builtTree, 1); // 2. 自动关联资源处理 if ("0".equals(pagination.getIsAuto())) { boolean matchAll = "0".equals(pagination.getMatchRule()); builtTree = bizAssetStructureTreeService.getAutoResources( builtTree, matchAll, (Integer) pagination.getUnitId() ); } // 返回结果 PageListVO vo = new PageListVO(); vo.setList(builtTree); PaginationVO page = JsonUtil.getJsonToBean(pagination, PaginationVO.class); vo.setPagination(page); return ActionResult.success(vo); } catch (Exception e) { log.error("生成实例化树模版失败", e); return ActionResult.fail(MsgCode.FA001.get()); } }/** * 生成完整的模版树 * * @param matchAll 资源匹配规则,全部还是默认 * @return 树形结构列 */ @Override public List<AssetStructureTreeNode> getAutoResources(List<AssetStructureTreeNode> logicTree, boolean matchAll, Integer unitId) { // 1. 通过机组ID查询所有相关资源 (五类资源) Map<AssetType, Map<Integer, Object>> allResources = fetchAllResourcesByUnit(unitId); // 2. 查询已绑定的资源ID和类型 Map<AssetType, Set<Integer>> boundResources = getBoundResourcesWithType(); // 3. 筛选未绑定的资源 Map<AssetType, Map<Integer, Object>> availableResources = filterAvailableResources(allResources, boundResources); // 4. 生成最终结构树 return generateFinalTree(logicTree, availableResources, matchAll); } // 第一步:获取机组关联的所有资源 private Map<AssetType, Map<Integer, Object>> fetchAllResourcesByUnit(Integer unitId) { Map<AssetType, Map<Integer, Object>> resources = new EnumMap<>(AssetType.class); // 1. 获取当前机组 BizBaseUnitEntity unit = unitService.getById(unitId); if (unit != null) { Map<Integer, Object> unitMap = new HashMap<>(); unitMap.put(unit.getId(), unit); resources.put(AssetType.UNIT, unitMap); } // 2. 获取机组下的系统 LambdaQueryWrapper<BizBaseSystemEntity> sysWrapper = new LambdaQueryWrapper<>(); sysWrapper.eq(BizBaseSystemEntity::getUnitId, unitId) .isNull(BizBaseSystemEntity::getDeletedAt); Map<Integer, Object> systems = systemService.list(sysWrapper).stream() .collect(Collectors.toMap(BizBaseSystemEntity::getId, Function.identity())); resources.put(AssetType.SYSTEM, systems); // 3. 获取系统下的设备 Set<Integer> sysIds = systems.keySet(); LambdaQueryWrapper<BizBaseDeviceEntity> deviceWrapper = new LambdaQueryWrapper<>(); deviceWrapper.in(!sysIds.isEmpty(), BizBaseDeviceEntity::getSysId, sysIds) .isNull(BizBaseDeviceEntity::getDeletedAt); Map<Integer, Object> devices = deviceService.list(deviceWrapper).stream() .collect(Collectors.toMap(BizBaseDeviceEntity::getId, Function.identity())); resources.put(AssetType.DEVICE, devices); // 4. 获取设备下的检修单元 Set<Integer> deviceIds = devices.keySet(); LambdaQueryWrapper<BizBaseRepaUnitEntity> repaWrapper = new LambdaQueryWrapper<>(); repaWrapper.in(!deviceIds.isEmpty(), BizBaseRepaUnitEntity::getDeviceId, deviceIds) .isNull(BizBaseRepaUnitEntity::getDeletedAt); Map<Integer, Object> repaUnits = repaUnitService.list(repaWrapper).stream() .collect(Collectors.toMap(BizBaseRepaUnitEntity::getId, Function.identity())); resources.put(AssetType.REPA_UNIT, repaUnits); // 5. 获取检修单元下的部件 Set<Integer> repaUnitIds = repaUnits.keySet(); LambdaQueryWrapper<BizBasePartsEntity> partsWrapper = new LambdaQueryWrapper<>(); partsWrapper.in(!repaUnitIds.isEmpty(), BizBasePartsEntity::getMaintUnitId, repaUnitIds) .isNull(BizBasePartsEntity::getDeletedAt); Map<Integer, Object> parts = partsService.list(partsWrapper).stream() .collect(Collectors.toMap(BizBasePartsEntity::getId, Function.identity())); resources.put(AssetType.PARTS, parts); return resources; } // 第二步:获取已绑定的资源(带类型信息) private Map<AssetType, Set<Integer>> getBoundResourcesWithType() { MPJLambdaWrapper<BizAssetStructureTreeEntity> wrapper = new MPJLambdaWrapper<>(); // 基础查询条件 wrapper.select(BizAssetStructureTreeEntity::getAssetId) .select(DictionaryDataEntity::getFullName) .isNotNull(BizAssetStructureTreeEntity::getAssetId) .isNull(BizAssetStructureTreeEntity::getDeletedAt); // 关联字典 wrapper.leftJoin(DictionaryDataEntity.class, DictionaryDataEntity::getF_id, BizAssetStructureTreeEntity::getTypeId); // 执行查询 List<Map<String, Object>> boundList = baseMapper.selectJoinMaps(wrapper); // 按资源类型分组 Map<AssetType, Set<Integer>> boundResources = new EnumMap<>(AssetType.class); for (Map<String, Object> item : boundList) { String typeName = (String) item.get("fullName"); Integer assetId = (Integer) item.get("assetId"); try { AssetType type = AssetType.fromName(typeName); boundResources.computeIfAbsent(type, k -> new HashSet<>()).add(assetId); } catch (IllegalArgumentException e) { log.warn("未知的资源类型: "+ typeName); } } return boundResources; } // 第三步:筛选可用资源(移除已绑定的) private Map<AssetType, Map<Integer, Object>> filterAvailableResources( Map<AssetType, Map<Integer, Object>> allResources, Map<AssetType, Set<Integer>> boundResources) { // 筛选后的资源 Map<AssetType, Map<Integer, Object>> available = new EnumMap<>(AssetType.class); // 有五类资源,使用循环,每次处理一类资源 for (AssetType type : allResources.keySet()) { Map<Integer, Object> typeResources = allResources.get(type); // 通过k获取boundResources中的值,如果没值就设置默认值Collections.emptySet()(空的集合) Set<Integer> boundIds = boundResources.getOrDefault(type, Collections.emptySet()); // 创建新map存储可用资源, Map<Integer, Object> availableMap = new HashMap<>(); // 如果typeResources中的id值不在boundIds中,就示这个资源未被绑定,可以使用 typeResources.forEach((id, resource) -> { if (!boundIds.contains(id)) { availableMap.put(id, resource); } }); available.put(type, availableMap); } return available; } // 第四步:生成最终结构树 private List<AssetStructureTreeNode> generateFinalTree( List<AssetStructureTreeNode> logicTree, Map<AssetType, Map<Integer, Object>> availableResources, boolean matchAll) { List<AssetStructureTreeNode> resultTree = new ArrayList<>(); // 这里看似是循环,实际上,resultTree只会有一个值。 for (AssetStructureTreeNode node : logicTree) { // 深度复制节点 AssetStructureTreeNode newNode = new AssetStructureTreeNode(node); // 但是不用复制子节点 newNode.setChildren(new ArrayList<>()); // 处理资源绑定 processNodeResources(newNode, availableResources, matchAll); // 递归处理子节点 if (!node.getChildren().isEmpty()) { newNode.setChildren(generateFinalTree(node.getChildren(), availableResources, matchAll)); } // 设置叶节点标志 newNode.setIsLeaf(newNode.getChildren().isEmpty()); resultTree.add(newNode); } return resultTree; } // 处理节点资源绑定 private void processNodeResources( AssetStructureTreeNode node, Map<AssetType, Map<Integer, Object>> availableResources, boolean matchAll) { try { AssetType nodeType = AssetType.fromName(node.getTypeIdName()); // 跳过结构树节点 if (nodeType == AssetType.STRUCTURE_TREE) { return; } // 获取该类型可用资源,比如说设备资源。key是设备枚举。v是map。所以使用nodeType,获取设备的全部资源。id为key,设备对象为v Map<Integer, Object> resources = availableResources.get(nodeType); if (resources == null || resources.isEmpty()) { return; } // 根据节点名称匹配资源 List<Object> matchedResources = new ArrayList<>(); for (Object resource : resources.values()) { // 获取资源名称,如果是设备就是设备中设备名称 String resourceName = getResourceName(resource, nodeType); // 如果资源名称包含节点名称,则添加 if (resourceName != null && resourceName.contains(node.getStructureName())) { matchedResources.add(resource); if (!matchAll && !matchedResources.isEmpty()) { break; // 只匹配第一个 } } } // 绑定匹配到的资源 if (!matchedResources.isEmpty()) { Object firstResource = matchedResources.get(0); bindResourceToNode(node, firstResource, nodeType); } } catch (IllegalArgumentException e) { log.warn("未知的节点类型: "+ node.getTypeIdName()); } } // 获取资源名称 private String getResourceName(Object resource, AssetType type) { switch (type) { case UNIT: return ((BizBaseUnitEntity) resource).getUnitName(); case SYSTEM: return ((BizBaseSystemEntity) resource).getSysName(); case DEVICE: return ((BizBaseDeviceEntity) resource).getDeviceName(); case REPA_UNIT: return ((BizBaseRepaUnitEntity) resource).getRepaUnitName(); case PARTS: return ((BizBasePartsEntity) resource).getPartsName(); default: return null; } } // 绑定资源到节点 private void bindResourceToNode(AssetStructureTreeNode node, Object resource, AssetType type) { switch (type) { case UNIT: BizBaseUnitEntity unit = (BizBaseUnitEntity) resource; node.setAssetId(unit.getId()); node.setAssetName(unit.getUnitName()); break; case SYSTEM: BizBaseSystemEntity system = (BizBaseSystemEntity) resource; node.setAssetId(system.getId()); node.setAssetName(system.getSysName()); break; case DEVICE: BizBaseDeviceEntity device = (BizBaseDeviceEntity) resource; node.setAssetId(device.getId()); node.setAssetName(device.getDeviceName()); node.setKks(device.getKks()); break; case REPA_UNIT: BizBaseRepaUnitEntity repaUnit = (BizBaseRepaUnitEntity) resource; node.setAssetId(repaUnit.getId()); node.setAssetName(repaUnit.getRepaUnitName()); break; case PARTS: BizBasePartsEntity part = (BizBasePartsEntity) resource; node.setAssetId(part.getId()); node.setAssetName(part.getPartsName()); break; } }
07-10
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值