java实现树形查询

4 篇文章 0 订阅
1 篇文章 0 订阅

首先这个树形查询,你肯定不能用他内置sql语句吧,所以这里我们自己在dao层写一句sql语句进行查询:

@Query(value = "select * from TB_UIM_MENU_TEST t START WITH t.PID IS NULL" +
        " CONNECT BY PRIOR t.ID = t.PID order by t.PID NULLS first,t.MENU_SORT ASC",nativeQuery = true)
List<MenuTestDTO> findTree();

这里我写的原生sql语句,不原生的俺也不会。
接下来就要实现树形查询了,service层代码我就不po出来了,直接po实现层的代码:

public List findTree() {

    List<MenuTreeVO> list = new ArrayList<>();
    List<MenuTestDTO> dataList = menuTestDAO.findTree();
    List<MenuTreeVO> resultList = new ArrayList<>();
    for (int i = 0; i < dataList.size(); i++) {
        MenuTestDTO menuTestDTO = dataList.get(i);
        MenuTreeVO menuTreeVO = new MenuTreeVO();
        menuTreeVO.setId(menuTestDTO.getId());
        menuTreeVO.setPid(menuTestDTO.getPid());
        menuTreeVO.setLockState(menuTestDTO.getLockState());
        menuTreeVO.setLogo(menuTestDTO.getLogo());
        menuTreeVO.setMenuSort(menuTestDTO.getMenuSort());
        menuTreeVO.setName(menuTestDTO.getName());
        menuTreeVO.setRoute(menuTestDTO.getMenuRoute());
        resultList.add(menuTreeVO);
    }
    for (int i = 0; i < resultList.size(); i++) {
        MenuTreeVO menuTreeVO = resultList.get(i);
        if (menuTreeVO.getPid() == null){
            //一级节点
            list.add(menuTreeVO);
        }else {
            //子节点
            findFather(menuTreeVO,list);
        }
    }
    return list;
}

到这里有人就要问了,你怎么知道不同子级对应的父级是哪个啊,问得好!在上述方法中有一个方法是findFather()这个就是进行父级寻找的方法,数据库里肯定是有关系的,下面看看这个findFather()方法:

private List findFather(MenuTreeVO private List findFather(MenuTreeVO menuTreeVO,List list){

    for (int i = 0; i < list.size(); i++) {
        MenuTreeVO menuvo = list.get(i);
        //判断是否为对应节点的子节点
        if (menuvo.getId().equals(menuTreeVO.getPid())){
            menuvo.getChildren().add(menuTreeVO);
        }
    }
    return null;
}

像我这里表中是有PID和ID的区别,子级的PID和父级的ID是一样的,而父级的PID是空的,所以第一个判断使用ID进行判断,如果ID为空那就是父级,把他取出来存在一个List当中,你得先声明空的集合奥,类似于汉诺塔那样。然后通过ID和PID的关系再去找子级,需要说的一点是,我这里用的是域对象转换,自己封装了一下,这个VO中有这么一个元素:

private List<MenuTreeVO> children = new ArrayList<>();

我只能说DDDD,这就是用来存子级的list对象。大概差不多就是这个意思,自己理解一下就行。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }
Java可以通过使用递归和面向对象的思想来实现树形菜单。面是一个简单的示例: 首先,我们需要定义一个树类,该类包含节点的值和子节点列表: ```java class TreeNode { private String value; private List<TreeNode> children; public TreeNode(String value) { this.value = value; this.children = new ArrayList<>(); } public void addChild(TreeNode child) { children.add(child); } public List<TreeNode> getChildren { return children; } public String getValue() { return value } } ``` 然后,我们可以创建一个树形菜单类,该类包含根节点和一些操作方法: ```java class TreeMenu { private TreeNode root; public TreeMenu(TreeNode root) { this.root = root; } public void printMenu() { printNode(root, 0); } private void printNode(TreeNode node, int level) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < level; i++) { sb.append(" "); // 每一层缩进两个空格 } sb.append(node.getValue()); System.out.println(sb.toString()); List<TreeNode> children = node.getChildren(); for (TreeNode child : children) { printNode(child, level + 1); } } } ``` 最后,我们可以使用上述类来创建树形菜单并打印出来: ```java public class Main { public static void main(String[] args) { TreeNode root = new TreeNode("Root"); TreeNode node1 = new TreeNode("Node 1"); TreeNode node2 = new TreeNode("Node 2"); TreeNode node3 = new TreeNode("Node 3"); TreeNode node11 = new TreeNode("Node 1.1"); TreeNode node12 = new TreeNode("Node 1.2"); TreeNode node21 = new TreeNode("Node 2.1"); root.addChild(node1); root.addChild(node2); root.addChild(node3); node1.addChild(node11); node1.addChild(node12); node2.addChild(node21); TreeMenu treeMenu = new TreeMenu(root); treeMenu.printMenu(); } } ``` 运行上述代码,将会输出以下树形菜单: ``` Root Node 1 Node 1.1 Node 1.2 Node 2 Node 2.1 Node 3 ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值