精华内容
下载资源
问答
  • 在项目开发过程中,需要对存在关联的数据库中的数据以树形结构在页面上进行展示,通过SQL语句难以进行处理,需要在程序的业务层进行处理。 1、数据 ① city_groups 说明: city_groups通过id 和 parent_id...

    问题:
    在项目开发过程中,需要对存在关联的数据库表中的数据以树形结构在页面上进行展示,通过SQL语句难以进行处理,需要在程序的业务层进行处理。

    1、数据表
    ① city_groups表
    在这里插入图片描述
    说明: city_groups表通过idparent_id进行自关联,parent_id00000000-0000-0000-0000-000000000000空UUID时,代表省份。

    ② persons表
    在这里插入图片描述
    说明: persons表通过 group_id 和 city_groups表中的id进行外关联。

    ③ phones表
    在这里插入图片描述
    说明: phones表中的 person_id 和 persons表中的id进行外关联。

    2、核心代码
    注意:对于city_groups表查出来的数据需要根据parent_id做升序处理,因为先找到父级,后面的子级才能往父级中添加。

    select * from city_groups order by parent_id asc
    

    ① TreeNode.java 封装数据,提供递归查找的方法

    @Data
    public class TreeNode {
        private String key;
        private String parentKey;
        private String name;
        private List<TreeNode> children = new ArrayList<>();
    
        public static TreeNode findNode(List<TreeNode> nodes, String key) {
            List<TreeNode> finds = new ArrayList<>();
            findNode(nodes, key, finds);
            return finds.size() != 0 ? finds.get(0) : null;
        }
    
        public static void findNode(List<TreeNode> nodes, String key, List<TreeNode> finds) {
            for (TreeNode node : nodes) {
                if (key.equals(node.getKey()))
                    finds.add(node);
    
                findNode(node.getChildren(), key, finds);
            }
        }
    }
    

    ② CityGroupImpl.java

    @Service
    public class CityGroupServiceImpl implements CityGroupService {
        private CityGroupMapper groupMapper;
        public CityGroupServiceImpl(CityGroupMapper groupMapper) {
            this.groupMapper = groupMapper;
        }
    
        @Override
        public List<TreeNode> getNodes() {
            List<TreeNode> nodes = new ArrayList<>();
    
            List<CityGroup> groups = groupMapper.getAll();
            for(CityGroup group: groups) {
                TreeNode node = toTreeNode(group);
                TreeNode parent = TreeNode.findNode(nodes, node.getParentKey());
                if (parent != null)
                    parent.getChildren().add(node);
                else
                    nodes.add(node);
            }
    
            return nodes;
        }
    
        private TreeNode toTreeNode(CityGroup group) {
            TreeNode node = new TreeNode();
            node.setKey(group.getId());
            node.setParentKey(group.getParentId());
            node.setName(group.getName());
            return node;
        }
    }
    

    ③ PersonServiceImpl.java

    @Service
    public class PersonServiceImpl implements PersonService {
        private PersonMapper personMapper;
        public PersonServiceImpl(PersonMapper personMapper) {
            this.personMapper = personMapper;
        }
    
        @Override
        public List<TreeNode> getNodes(List<TreeNode> nodes) {
            List<Person> persons = personMapper.selectList(null);
            for (Person person : persons) {
                TreeNode node = toTreeNode(person);
                TreeNode parent = TreeNode.findNode(nodes, node.getParentKey());
                if (parent != null)
                    parent.getChildren().add(node);
                else
                    nodes.add(node);
            }
    
            return nodes;
        }
    
        private TreeNode toTreeNode(Person person) {
            TreeNode node = new TreeNode();
            node.setKey(person.getId());
            node.setParentKey(person.getGroupId());
            node.setName(person.getName());
            return node;
        }
    }
    

    ④ PhoneServiceImpl.java

    @Service
    public class PhoneServiceImpl implements PhoneService {
        private PhoneMapper phoneMapper;
        public PhoneServiceImpl(PhoneMapper phoneMapper) {
            this.phoneMapper = phoneMapper;
        }
    
        @Override
        public List<TreeNode> getNodes(List<TreeNode> nodes) {
            List<Phone> phones = phoneMapper.selectList(null);
            for (Phone phone : phones) {
                TreeNode node = toTreeNode(phone);
                TreeNode parent = TreeNode.findNode(nodes, node.getParentKey());
                if (parent != null)
                    parent.getChildren().add(node);
                else
                    nodes.add(node);
            }
    
            return nodes;
        }
    
        private TreeNode toTreeNode(Phone phone) {
            TreeNode node = new TreeNode();
            node.setKey(phone.getId());
            node.setParentKey(phone.getPersonId());
            node.setName(phone.getName());
            return node;
        }
    }
    

    ⑤ PhoneController.java

    @RestController
    @RequestMapping("/phone")
    public class PhoneController {
        private PhoneService phoneService;
        private PersonService personService;
        private CityGroupService groupService;
        public PhoneController(PersonService personService, CityGroupService groupService, PhoneService phoneService) {
            this.phoneService = phoneService;
            this.groupService = groupService;
            this.personService = personService;
        }
    
        @GetMapping("/getNodes")
        public List<TreeNode> getNodes() {
            List<TreeNode> nodes = groupService.getNodes();
            nodes = personService.getNodes(nodes);
            nodes = phoneService.getNodes(nodes);
            return nodes;
        }
    }
    

    3、Postman测试
    在这里插入图片描述

    展开全文
  • java递归生成树形结构菜单

    万次阅读 多人点赞 2019-01-04 16:59:01
    一、mysql,数据自行准备 CREATE TABLE `sys_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pid` bigint(20) DEFAULT NULL, `title` varchar(255) CHARACTER SET utf8 DEFAULT NULL, `path` varchar(255)...

    一、mysql表,数据自行准备

    CREATE TABLE `sys_menu` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `pid` bigint(20) DEFAULT NULL,
      `title` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
      `path` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
      `level` int(11) DEFAULT NULL,
      `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
      `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=200 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci

    二、创建对应的实体类

    public class Menu implements Serializable {
    	
    	private static final long serialVersionUID = -5990021029947688358L;
    	
    	private Integer id;
    	private String title;//菜单标题
    	private String path;//路径
    	private Integer pid;//父菜单ID 一级菜单pid为null
    	private Integer level;//级别,排序用
    	
    	private List<Menu> children = new ArrayList<Menu>();
    
    	public Integer getId() {
    		return id;
    	}
    
    	public void setId(Integer id) {
    		this.id = id;
    	}
    
    	public String getTitle() {
    		return title;
    	}
    
    	public void setTitle(String title) {
    		this.title = title;
    	}
    
    	public String getPath() {
    		return path;
    	}
    
    	public void setPath(String path) {
    		this.path = path;
    	}
    
    	public Integer getPid() {
    		return pid;
    	}
    
    	public void setPid(Integer pid) {
    		this.pid = pid;
    	}
    
    	public Integer getLevel() {
    		return level;
    	}
    
    	public void setLevel(Integer level) {
    		this.level = level;
    	}
    
    	public List<Menu> getChildren() {
    		return children;
    	}
    
    	public void setChildren(List<Menu> children) {
    		this.children = children;
    	}
    }

    三、递归组装树形结构函数实现

            /**
             * @方法名: parseMenuTree<br>
             * @描述: 组装菜单<br>
             * @param list 数据库里面获取到的全量菜单列表
             * @return
             */
            public static List<Menu> parseMenuTree(List<Menu> list){
    	    List<Menu> result = new ArrayList<Menu>();
    		
    	    // 1、获取第一级节点
    	    for (Menu menu : list) {
    	        if(null == menu.getPid()) {
    		    result.add(menu);
    		}	
    	    }
    		
    	    // 2、递归获取子节点
    	    for (Menu parent : result) {
    		parent = recursiveTree(parent, list);
    	    }
    		
    	    return result;
    	}
    	
    	public static Menu recursiveTree(Menu parent, List<Menu> list) {
    	    for (Menu menu : list) {
    	        if(Objects.equals(parent.getId(),menu.getPid())) {
    		    menu = recursiveTree(menu, list);
    		    parent.getChildren().add(menu);
    		}
    	    }
    		    
    	    return parent;
    	}

    四、从数据库获取菜单数据,调用组装菜单函数生成树形结构的数据

            public static void main(String[] args) {
    		
    		List<Menu> list = new ArrayList<Menu>();
    		//TODO 这里从数据库获取全量菜单后放到list中
    		
    		//树形结构数据生成
    		List<Menu> result = parseMenuTree(list);
    		
    		System.out.println(JSONObject.toJSONString(result));
    	}

     

    展开全文
  • 展开全部1、准备表结构及对应的数据32313133353236313431303231363533e4b893e5b19e31333361306462a、表结构:create table TB_TREE(CID NUMBER not null,CNAME VARCHAR2(50),PID NUMBER //父节点)b、数据:...

    展开全部

    1、准备表结构及对应的表数据32313133353236313431303231363533e4b893e5b19e31333361306462

    a、表结构:

    create table TB_TREE

    (

    CID NUMBER not null,

    CNAME VARCHAR2(50),

    PID NUMBER //父节点

    )

    b、表数据:

    insert into tb_tree (CID, CNAME, PID) values (1, '中国', 0);

    insert into tb_tree (CID, CNAME, PID) values (2, '北京市', 1);

    insert into tb_tree (CID, CNAME, PID) values (3, '广东省', 1);

    insert into tb_tree (CID, CNAME, PID) values (4, '上海市', 1);

    insert into tb_tree (CID, CNAME, PID) values (5, '广州市', 3);

    insert into tb_tree (CID, CNAME, PID) values (6, '深圳市', 3);

    insert into tb_tree (CID, CNAME, PID) values (7, '海珠区', 5);

    insert into tb_tree (CID, CNAME, PID) values (8, '天河区', 5);

    insert into tb_tree (CID, CNAME, PID) values (9, '福田区', 6);

    insert into tb_tree (CID, CNAME, PID) values (10, '南山区', 6);

    insert into tb_tree (CID, CNAME, PID) values (11, '密云县', 2);

    insert into tb_tree (CID, CNAME, PID) values (12, '浦东', 4);

    2、TreeNode对象,对应tb_tree

    public class TreeNode implements Serializable {

    private Integer cid;

    private String cname;

    private Integer pid;

    private List nodes = new ArrayList();

    public TreeNode() {

    }

    //getter、setter省略

    }

    3、测试数据

    public class TreeNodeTest {

    @Test

    public void loadTree() throws Exception{

    System.out.println(JsonUtils.javaToJson(recursiveTree(1)));

    }

    /**

    * 递归算法解析成树形结构

    *

    * @param cid

    * @return

    * @author jiqinlin

    */

    public TreeNode recursiveTree(int cid) {

    //根据cid获取节点对象(SELECT * FROM tb_tree t WHERE t.cid=?)

    TreeNode node = personService.getreeNode(cid);

    //查询cid下的所有子节点(SELECT * FROM tb_tree t WHERE t.pid=?)

    List childTreeNodes = personService.queryTreeNode(cid);

    //遍历子节点

    for(TreeNode child : childTreeNodes){

    TreeNode n = recursiveTree(child.getCid()); //递归

    node.getNodes().add(n);

    }

    return node;

    }

    }

    输出的json格式如下:

    {

    "cid": 1,

    "nodes": [

    {

    "cid": 2,

    "nodes": [

    {

    "cid": 11,

    "nodes": [

    ],

    "cname": "密云县",

    "pid": 2

    }

    ],

    "cname": "北京市",

    "pid": 1

    },

    {

    "cid": 3,

    "nodes": [

    {

    "cid": 5,

    "nodes": [

    {

    "cid": 7,

    "nodes": [

    ],

    "cname": "海珠区",

    "pid": 5

    },

    {

    "cid": 8,

    "nodes": [

    ],

    "cname": "天河区",

    "pid": 5

    }

    ],

    "cname": "广州市",

    "pid": 3

    },

    {

    "cid": 6,

    "nodes": [

    {

    "cid": 9,

    "nodes": [

    ],

    "cname": "福田区",

    "pid": 6

    },

    {

    "cid": 10,

    "nodes": [

    ],

    "cname": "南山区",

    "pid": 6

    }

    ],

    "cname": "深圳市",

    "pid": 3

    }

    ],

    "cname": "广东省",

    "pid": 1

    },

    {

    "cid": 4,

    "nodes": [

    {

    "cid": 12,

    "nodes": [

    ],

    "cname": "浦东",

    "pid": 4

    }

    ],

    "cname": "上海市",

    "pid": 1

    }

    ],

    "cname": "中国",

    "pid": 0

    }

    本回答由网友推荐

    2Q==

    已赞过

    已踩过<

    你对这个回答的评价是?

    评论

    收起

    展开全文
  • 项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同...

    项目中经常会遇到各种需要以树形结构展示的功能,比较常见的,如菜单树,分类树,部门树等等,如果为每种类型都遍历递归生成树形结构返回给前端,显得有些冗余且麻烦,并且其实逻辑都是一致的,只是遍历的对象不同而已,故其实可以通过面向接口思维,来实现这种通用工具类的实现。

    TreeNode用来表示每个树节点的抽象,即需要生成树的对象需要实现此接口。

    /**

    * 树节点父类,所有需要使用{@linkplain TreeUtils}工具类形成树形结构等操作的节点都需要实现该接口

    *

    * @param 节点id类型

    */

    public interface TreeNode {

    /**

    * 获取节点id

    *

    * @return 树节点id

    */

    T id();

    /**

    * 获取该节点的父节点id

    *

    * @return 父节点id

    */

    T parentId();

    /**

    * 是否是根节点

    *

    * @return true:根节点

    */

    boolean root();

    /**

    * 设置节点的子节点列表

    *

    * @param children 子节点

    */

    void setChildren(List extends TreeNode> children);

    /**

    * 获取所有子节点

    *

    * @return 子节点列表

    */

    List extends TreeNode> getChildren();

    }

    复制代码

    TreeUtils用来生成树形结构,以及获取所有叶子节点等操作

    /**

    * 树形结构工具类

    *

    * @author meilin.huang

    * @version 1.0

    * @date 2019-08-24 1:57 下午

    */

    public class TreeUtils {

    /**

    * 根据所有树节点列表,生成含有所有树形结构的列表

    *

    * @param nodes 树形节点列表

    * @param 节点类型

    * @return 树形结构列表

    */

    public static > List generateTrees(List nodes) {

    List roots = new ArrayList<>();

    for (Iterator ite = nodes.iterator(); ite.hasNext(); ) {

    T node = ite.next();

    if (node.root()) {

    roots.add(node);

    // 从所有节点列表中删除该节点,以免后续重复遍历该节点

    ite.remove();

    }

    }

    roots.forEach(r -> {

    setChildren(r, nodes);

    });

    return roots;

    }

    /**

    * 从所有节点列表中查找并设置parent的所有子节点

    *

    * @param parent 父节点

    * @param nodes 所有树节点列表

    */

    @SuppressWarnings("all")

    public static void setChildren(T parent, List nodes) {

    List children = new ArrayList<>();

    Object parentId = parent.id();

    for (Iterator ite = nodes.iterator(); ite.hasNext(); ) {

    T node = ite.next();

    if (Objects.equals(node.parentId(), parentId)) {

    children.add(node);

    // 从所有节点列表中删除该节点,以免后续重复遍历该节点

    ite.remove();

    }

    }

    // 如果孩子为空,则直接返回,否则继续递归设置孩子的孩子

    if (children.isEmpty()) {

    return;

    }

    parent.setChildren(children);

    children.forEach(m -> {

    // 递归设置子节点

    setChildren(m, nodes);

    });

    }

    /**

    * 获取指定树节点下的所有叶子节点

    *

    * @param parent 父节点

    * @param 实际节点类型

    * @return 叶子节点

    */

    public static > List getLeafs(T parent) {

    List leafs = new ArrayList<>();

    fillLeaf(parent, leafs);

    return leafs;

    }

    /**

    * 将parent的所有叶子节点填充至leafs列表中

    *

    * @param parent 父节点

    * @param leafs 叶子节点列表

    * @param 实际节点类型

    */

    @SuppressWarnings("all")

    public static void fillLeaf(T parent, List leafs) {

    List children = parent.getChildren();

    // 如果节点没有子节点则说明为叶子节点

    if (CollectionUtils.isEmpty(children)) {

    leafs.add(parent);

    return;

    }

    // 递归调用子节点,查找叶子节点

    for (T child : children) {

    fillLeaf(child, leafs);

    }

    }

    }

    复制代码

    具体使用方式之声明树节点对象

    @Getter

    @Setter

    public class ResourceListVO implements TreeNode {

    private Long id;

    private Long pid;

    private Integer type;

    private String name;

    private String icon;

    private String code;

    private Integer status;

    private List children;

    @Override

    public Long id() {

    return this.id;

    }

    @Override

    public Long parentId() {

    return this.pid;

    }

    @Override

    public boolean root() {

    return Objects.equals(this.pid, 0L);

    }

    @Override

    public void setChildren(List children) {

    this.children = children;

    }

    }

    复制代码

    具体使用方式之调用

    /**

    * 获取账号的资源树

    */

    public List listByAccountId(Long accountId) {

    return TreeUtils.generateTrees(BeanUtils.copyProperties(mapper.selectByAccountId(userId), ResourceListVO.class));

    }

    复制代码

    通过使用TreeUtils工具可以统一方便地生成一切对象的树形结构以及其他一些对树的操作,避免对每个对象都用特定代码生成。使用起来就是几个字简洁方便爽歪歪biu特否。更多有趣方便的工具及代码可以去个人业余练手项目中获取哈gitee.com/objs/mayfly

    展开全文
  • 数据库有这些字段:ID,BOOK_NAME,BOOK_AUTHOR,BOOK_PUBLISH,BOOK_DATE,BOOK_ISBN,BOOK_PAGE,BOOK_PR今天遇到一个问题,就是excel中的数据是树形的,需要读进数据库,并保存树形结构,excel结构,程序代码如下。...
  • 假如数据库表结构是 id,pid这种表结构类型@Testpublic void testJsonTree(){List selectAll = buildData();Map linkMap=new LinkedHashMap<>();List linkList=new LinkedList<>();for (Map entity : ...
  • 业务场景:xlsx表格当中有5个层级,在导入项目中时要确保页面展示的结构树形,但是有一些的零部件从属(父类编号)是一样的,这样就给导入表格的程序导致分别不出有一些的零部件是在哪一级的父类下面,所以导入...
  • 表结构对应的实体类。 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import java.util.ArrayList; import java.util.List; @Data @AllArgsConstructor @
  • cn.hutoolhutool-all5.5.8引入好依赖之后 可以直接在一个新建的方法中使用工具生成适合自己的开发树形逻辑考虑到菜单等需求的普遍性,有用户提交了一个扩展性极好的树状结构实现。这种树状结构可以根据配置文件灵活...
  • 我们经常要根据数据库的结构,生成树形结构在页面显示;下面就是一个例子: 页面的tree组件采用的是EasyUI 的 Tree 组件。 数据库结构: 名称: tDict Id name parentid sortid valid 主键 名称 父ID 排序ID ...
  • mysql数据库的部门结构: 需求:将部门的树形结构数据已JSON形式...4、在java中进行遍历生成树形菜单 具体操作如下: 1、部门的实体VO @Data public class DepartmentVO { private int id; //部门ID private.
  • 1.后端框架:struts22.mysql数据库的部门表结构:image.png3.最终实现效果image.png4.通过jpa生成实体类image.png5.编写MenuVoprivate int id;//菜单idprivate String menuname;//菜单名称private String menuurl;//...
  • /*** @Description 生成树形结构nodeTree; List tagList原始无序数据链表* @auther: wz* @date: 2019/1/18 15:09*/private List createNodeTree(List tagList) {long beginTime = System.currentTimeMillis();logger...
  • 我最近写到了一个项目中用到了树形图,不得不说这个树形...二、生成树结构public static list findtree(list allmenu){ //这里treevo是我写了一个跟layui树形结构一样结构的实体类,wfunit是我数据库的实体类。/...
  • 一、表结构(ORACLE): 二、数据 1、统计报表(TJBB),存储报表的基本信息。 2、统计报表明细(TJBBMX),存储报表的指标信息。 注意:TJLX字段为3位数字(0或1)组成。每位数字分别代表:今年,去年,同比。...
  • 一、基本概况上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合自己对于的理解,然后用一种非递归的方式进行树结构数据的处理。首先,改造数据库设计,加入度的概念:首先,layer的设计,是...
  • 上一篇博客介绍到用递归实现树结构数据的查找,那么这篇博客,我就结合自己对于的理解,然后用一种非递归的方式进行树结构数据的处理。首先,改造数据库设计,加入度的概念: 首先,layer的设计,是来源于...
  • 最近,我接手了一个二次开发的WEB系统,是springmvc的架构,但是,当我完成了某个子模块应用程序的开发,准备把源...请指教如何写这段拼接SQL语句来实现这种JAVA代码自动扫描数据库生成新的带URL的节点,谢谢。
  • SQL Server 2005开始,我们可以直接通过CTE来支持递归查询,CTE即公用表表达式百度百科公用表表达式(CTE),是一个在查询中定义的临时命名结果...创建的语法是:with ()as()select * from 生成数据--菜单目录结构表cr...
  • SQL Server 2005开始,我们可以直接通过CTE来支持递归查询,CTE即公用表表达式百度百科公用表表达式(CTE),是一个在查询中定义的临时命名结果...创建的语法是:with ()as()select * from 1、生成数据--菜单目录结构表...
  • java递归生成菜单

    2020-06-04 16:57:50
    递归组装树形结构函数实现 mysql 数据自行准备 CREATE TABLE `sys_menu` ( `id` int(11) NOT NULL AUTO_INCREMENT, `pid` bigint(20) DEFAULT NULL, `title` varchar(255) CHARACTER SET utf8 DEFAULT NULL...
  • 基于数据库动态生成树形目录

    千次阅读 2004-01-14 11:09:00
    一、 目录树的广泛应用 为了这段内容,在百度上搜了搜,内容一大通,相关的竟没有。搜什么搜嘛?...清了清嗓子:在我们项目中常常会出现自关联的数据,从整体看去,整个就呈现为一个树形数据结构。当
  • 1、可以生成动态表头,单级,多级都支持,尤其是树形表头(整体思路按照树形结构数据来遍历); 2、数据可配置,支持动态填写数据(一个List结构的数据); 3、读取Excel数据; 设计思路:需要一个含有树形结构的...
  • 树形菜单能很好的呈现菜单项之前的从属关系,结构清晰明了。J-hi平台提供了自定义树形菜单的功能,通过简单的配置即可实现。本文主要介绍通过树形菜单选择带回节点值的实现方法。以选择带回行政区划位置为例。数据库...
  • java算法与数据结构

    2012-04-14 12:34:38
    3.树形结构 (1)二叉树的性质及存储结构 (2)二叉树的遍历 (3)线索二叉树 (4)树的存储结构 (5)树、二叉树与森林的转化方法 (6)哈夫曼树 (7)二叉排序树及平衡化 (8)堆排序树 (9)B-树 4.图形结构 ...
  • 树形网格(TreeGrid)可以展示有限空间上带有多列和复杂数据电子 一、案例一:按tree的数据结构生成 前台 <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding=...
  • 通过树形展示库表结构,可以对表进行自定义归类,在线更新注释。你还可以使用它来部分替代mybatis generator的代码生成 功能。Features一键生成下载mybatis资源对表进行目录分类展示表结构信息分表只展示其中一个...

空空如也

空空如也

1 2 3 4 5
收藏数 90
精华内容 36
关键字:

java生成树形结构表

java 订阅