关于树形结构查询的接口设计

这篇具有很好参考价值的文章主要介绍了关于树形结构查询的接口设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

在实际开发中,经常会遇到树形结构的查询,如:菜单树、公司组织机构树、地区区划树等等业务,这里写下两个接口设计方案以供日后使用。

1.表结构设计

//一般单表树形结构基本上都为以下结构:
id,name,parentId,其他业务指标
//多表树形同理,设计思路都是通过parentId关联在一起

2.树形返回类设计

@Data
public class TreeNodeNew implements Serializable {

    private String id;
	//名称
    private String name;
	//上级id
    private String parentId;
	//子节点
    private List<TreeNodeNew> childrenTreeNode;
    //其他业务字段...
}

3.树形方案一:递归获取全部父子节点(若数据量太大则不推荐用此方法)

	//传入需查询的根节点
    public List<TreeNodeNew> findTree(String node) {
    	if(StrUtil.isEmpty(node)){
            node = 当前登录人所绑定的node节点
        }
        //LambdaQueryWrapper<TreeEntity>wrapper = new LambdaQueryWrapper<>();
        //wrapper.likeRight(TreeEntity::getId,node);
        //查出全部数据,这里可以优化:想办法只查询出需要的所有数据,比如51-5101-510101这种格式的结构like51就行
        List<TreeEntity> treeList = list(wrapper);
        //转为返回树形集合对象
        List<TreeNodeNew> trees = treeList.stream().map(op -> {
            TreeNodeNew tree = new TreeNodeNew();
            tree.setId(op.getCode());
            tree.setParentId(op.getParentId());
            tree.setName(op.getName());
            return tree;
        }).collect(Collectors.toList());
        //用传入的根节点做第一级,调用getChildren设置所有下属节点
        List<TreeNodeNew> collect = trees .stream()
                .filter(item -> node.equals(item.getId()))
                .map(item -> {
                    item.setChildrenTreeNode(getChildren(item, trees));
                    return item;
                }).sorted(Comparator.comparing(TreeNodeNew::getId)).
                collect(Collectors.toList());

         return collect;
	}
	//传入父节点和所有数据节点信息集合,先查出所有父节点id为传入父节点id的下属数据,再递归set下属数据的childrens
    private static List<TreeNodeNew> getChildren(TreeNodeNew treeEntity, List<TreeNodeNew> treeEntityList) {
        List<TreeNodeNew> collect = treeEntityList.stream()
                .filter(item -> treeEntity.getId().equals(item.getParentId()))
                .map(item -> {
                    item.setChildrenTreeNode(getChildren(item, treeEntityList));
                    return item;
                }).sorted(Comparator.comparing(TreeNodeNew::getId))
                .collect(Collectors.toList());
        return collect;
    }

4.树形方案二:懒加载

//懒加载实现:每次传入一个根节点,只需要返回所有parentId为传入根节点的数据集合即可,前端每次拿到数据
//显示在根节点下面,点一次不同根节点请求一次,渲染一次
    public List<TreeEntity> findTree(String node) {
        LambdaQueryWrapper<TreeEntity> wrapper = new LambdaQueryWrapper<>();
        //当传入根节点为空时,为第一次进入,默认返回该根节点信息
        if(StrUtil.isEmpty(node)){
        	node = "";//根节点id
            wrapper.eq(TreeEntity::getId,node);
        }else{
        //否则返回所有父节点id为传入根节点id的下级信息
            wrapper.eq(TreeEntity::getParentId,node);
        }
        List<TreeEntity> list = list(wrapper);
        return list;
   	}

5.总结:用方案一递归返回,优点是前端可以一次性拿到所有数据节点信息,相比懒加载不用点一次下级请求一次,只是第一次请求时效率慢点,可以考虑加缓存,但也要维护缓存。缺点是在数据量特别大的时候效率相当慢,如全国行政区划这种就适合用方案二懒加载形式,以时间换空间,方案一则相反。方案二优点是接口设计简单,维护容易。缺点是需要频繁请求数据来渲染页面。

文章来源地址https://www.toymoban.com/news/detail-508488.html

到了这里,关于关于树形结构查询的接口设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包