将平铺数据处理成层级数据的疑问

将平铺数据处理成层级数据的疑问

问题描述:

问题中使用的如下代码:

@WebServlet("/api/user_info")
public class UserInfoServlet extends HttpServlet {
    private RbacService rbacService = new RbacService();
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String uid = request.getParameter("uid");
        List<Node> nodes = rbacService.selectNodeByUserId(Long.parseLong(uid));
        List<Map> treeList = new ArrayList<>();
        Map module = null;
        for (Node node : nodes) {
            if (node.getNodeType() == 1){
                module = new LinkedHashMap();
                module.put("node", node);
                module.put("children", new ArrayList<>());
                treeList.add(module);
            } else if (node.getNodeType() == 2) {
                List children = (List) module.get("children");
                children.add(node);
            }
        }
        String json = new ResponseUtils().put("nodeList", treeList).toJsonString();
        response.setContentType("application/json;charset=utf-8");
        response.getWriter().println(json);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

对数据进行处理需要原本的数据严格的按照模块,功能,功能,功能的顺序进行排列。如果在未来加功能,就会造成混乱。比如模块一的功能添加在模块五的后面。所以这样子处理数据应该不太适用通用场合吧?

尝试过的解决方式:

不过我对这个知识点的理解是这样的:

这里的弊端就是要求数据库中的模块和功能是按顺序排列的。模块后面接着是相关的功能。不过思想上就是将数据弄出上下级结构,这里的LinkedHashMap搭配ArrayList就是核心的思想。把ArrayList放进LinkedHashMap就形成了次一级的结构,也就是在LinkedHashMap的非集合数据是一级,在其中的集合数据自然就成了二级。一个模块对应一个LinkedHashMap,一个LinkedHashMap中存放一个模块信息以及一个ArrayList,这个ArrayList用来存放模块下的功能。


最后我们可以把整理好的模块放入一个List<Map>中进行保存,方便一次性进行json序列化,然后把数据传输给View层。


我的理解是否有误?

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学你好,同学的理解是正确的。

1.课程中的数据库设计本身是有一点问题的,实际开发的时候并不会这么处理。这里只是为了演示一种特殊情况的处理方式,即在数据库设计时没有按照层级进行设计,而是后期通过主键进行处理。实际上,多数情况下数据库会在设计时考虑到这点,会在字段上加上例如父节点id这样的字段来进行处理。

2.上一条中父节点的案例在学习MySql的时候处理过,只不过当时只关注sql语句而不是业务逻辑,例如工资值和工资等级。

如果这里也是按照父子节点进行处理,就不需要使用这种方式了,可以通过表关联查询,然后在代码中判断父节点id值,然后生成集合就可以了。

祝学习愉快~

  • 只能卷了 提问者 #1

    另外我想的是在实体类里面也使用之前讲的1对多关系,比如在模块类中加一个ArrayList<功能>属性。通过查询返回模块类的一个List<Module> list。也就可以直接获取本身就有层级的数据了,然后直接

    new ResponseUtils().put("ModuleList", list).toJsonString();

    前端就可以得到拥有所有模块,并且模块下有所有相关功能的json字符串了。


    对于老师您说的代码中判断id值,我在想,这样甚至可以不做关联表查询。我是这么想的:

    在这里我们通过查询分别去获取List<模块>与List<功能>,然后通过判断获得符合moduleId值的功能类对象,再把模块和功能整合变成Map就和课程里的那样,再把循环中一个一个处理好的Map放进一个List<Map>,最后进行json序列化返回。


    请问我的理解是否正确?两种方法都是可以的吧。


    2023-02-14 19:43:51
  • 好帮手慕小蓝 回复 提问者 只能卷了 #2

    同学你好,实现的思路是不唯一的,可以根据库表和业务逻辑灵活选择,同学的实现方式都是可以的。

    祝学习愉快~

    2023-02-15 09:48:35
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师