java 一次查询数据库生成树形结构

@Override
public ResultObj getMenu() throws Exception {
    MenuDomain resultMenuDomain = new MenuDomain();
    List<MenuDomain> allMenu = menuDao.getMenu();
    //目录无限制
    for (MenuDomain menuItem : allMenu) {
        //第一层
        if (menuItem.getPid() == 0) {
            resultMenuDomain = menuItem;
            resultMenuDomain.setList(this.getSonMenuList(menuItem.getId(),allMenu));
        }
    }
    ResultObj resultObj = new ResultObj();
    return resultObj;
}

private List<MenuDomain> getSonMenuList(Integer id ,List<MenuDomain> allMenu) {
    List<MenuDomain> listvo = new ArrayList<>();
    for (MenuDomain menuItem : allMenu) {
        if (menuItem.getPid() == id) {//找到父级相同的下级
            listvo.add(menuItem);
        }
    }
    if(listvo.size() > 0){
        for(MenuDomain vo:listvo){
            vo.setList(getSonMenuList(vo.getId(),allMenu));
        }
    }
    return listvo;
}
/** * 根据等级查询类目树 * * @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; }
要实现树形结构图,需要先有一个树形结构的数据模型,然后通过查询数据库获取数据,最后通过递归生成树形结构。以下是一个简单的示例: 1. 数据模型 假设我们有一个格叫做`category`,它有以下字段: - id:分类的唯一标识 - name:分类的名称 - parent_id:父分类的id(如果没有父分类,则为null) 我们可以用一个Java类来示这个数据模型: ``` public class Category { private int id; private String name; private Integer parentId; // 注意这里用了Integer类型,因为parent_id可能为null // 省略getter和setter } ``` 2. 查询数据库 我们可以使用JDBC或ORM框架(如MyBatis、Hibernate等)来查询数据库,这里以MyBatis为例: ``` @Mapper public interface CategoryMapper { @Select("SELECT id, name, parent_id FROM category ORDER BY parent_id, id") List<Category> findAll(); } ``` 这里的`@Mapper`和`@Select`是MyBatis的注解,示这是一个Mapper接口,以及查询所有的分类数据。 3. 生成树形结构 最后,我们可以使用递归来生成树形结构。首先,我们需要定义一个方法,它的输入是所有的分类数据,输出是一个根节点: ``` public CategoryNode buildTree(List<Category> categories) { Map<Integer, CategoryNode> nodes = new HashMap<>(); // 用Map来快速查找节点 // 遍历所有分类,创建节点 for (Category category : categories) { CategoryNode node = new CategoryNode(category.getId(), category.getName()); nodes.put(category.getId(), node); } // 遍历所有分类,连接父子节点 for (Category category : categories) { Integer parentId = category.getParentId(); if (parentId != null) { CategoryNode parent = nodes.get(parentId); CategoryNode child = nodes.get(category.getId()); parent.addChild(child); } } // 最后返回根节点 for (CategoryNode node : nodes.values()) { if (node.getParent() == null) { return node; } } return null; // 如果没有根节点,则返回null } ``` 这个方法的思路很简单:先遍历所有分类,创建对应的节点并存储到Map中;然后再遍历所有分类,连接父子节点;最后找到根节点并返回。这里的`CategoryNode`是一个自定义的类,它示一个节点: ``` public class CategoryNode { private int id; private String name; private List<CategoryNode> children = new ArrayList<>(); private CategoryNode parent; public CategoryNode(int id, String name) { this.id = id; this.name = name; } public void addChild(CategoryNode child) { children.add(child); child.setParent(this); } // 省略getter和setter } ``` 这个类有四个属性:id、name、children、parent。其中,children示它的子节点,parent示它的父节点。addChild方法用于添加子节点时同时设置父子关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值