树形结构的构建

两种常用的构建树形结构的方式

  • 1:维护路径,通过路径一次将所有的节点查询出来,并制定key为节点的id,然后将所有的节点构建为一颗树
    • 优点:与数据库只交互一次,构建节点的时间为O(N)
    • 缺点:维护复杂,需要维护额外的路径
  • 2:递归查询,直接构建为一棵树
    • 优点:无脑递归插叙
    • 缺点:如果在数据库中递归,关系联查询N次,如果是在代码中递归,与数据库交互查询N减最后一层节点次

表结构如下

CREATE TABLE `t_lq_tree` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `mid` int(11) NOT NULL COMMENT '我的id',
  `pid` int(11) NOT NULL COMMENT '父id',
  `name` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '名字',
  `path` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '路径',
  `level` int(255) DEFAULT NULL COMMENT '层级',
  PRIMARY KEY (`id`),
  UNIQUE KEY `inx_mid` (`mid`),
  KEY `inx_pid` (`pid`),
  KEY `inx_path` (`path`)
) ENGINE=InnoDB AUTO_INCREMENT=1190 DEFAULT CHARSET=latin1;

先简单的:mybatis递归查询

1、mapper查询

    @Select("select * from t_lq_tree where mid=#{mid}")
    @Results({
            @Result(property = "children",column = "mid",
                    many = @Many(select="com.lq.bootmultiple.mapper.mysqlmapper.TreeMapper.getAllNodeXByPid"))
    })
    NodeX getNodeXByMid(Integer mid);

    @Select("select * from t_lq_tree where pid=#{mid}")
    @Results({
            @Result(property = "children",column = "mid",
                    many = @Many(select="com.lq.bootmultiple.mapper.mysqlmapper.TreeMapper.getAllNodeXByPid"))
    })
    List<NodeX> getAllNodeXByPid(@Param("mid") Integer mid);

2、对应的do对象

@Data
public class NodeX {
    /** 主键 */
    private Long id;
    /** 名称 */
    private String name;
    /** 路径 */
    private String path;
    /** 等级 */
    private int level;
    /** 自己的id */
    private Long mid;
    /** 父id */
    private Long pid;
    /** 子集 */
    private List<NodeX> children;
}

3、获取树形结构

NodeX nodeXByMid = treeMapper.getNodeXByMid(1);

维护路径的方式构建树

1、mapper

 @MapKey("mid")
    @Select("select * from t_lq_tree where path like " +
            "concat((select path from test.t_lq_tree where mid=#{mid}),'%')")
    Map<Integer,Node> getAllNodeByMid(Integer mid);

2、do对象

@Data
public class BaseTreeNode implements Serializable {

    /** 自己的id */
    private Long mid;
    /** 父id */
    private Long pid;
    /** 子集 */
    private List<BaseTreeNode> children;
}
@Data
public class Node extends BaseTreeNode{
    /** 主键 */
    private Long id;
    /** 名称 */
    private String name;
    /** 路径 */
    private String path;
    /** 等级 */
    private int level;

}

2、构建树形结构

     /**
     * 从任意节点构建一颗树
     * @param nodeMap  节点集合 key是mid
     * @param nodeId   当前跟节点
     * @return
     */
    public static <T extends BaseTreeNode> T buildTree(Map<Integer, ? extends BaseTreeNode> nodeMap, Long nodeId) {
        // 树
        BaseTreeNode node = new BaseTreeNode();
        List<BaseTreeNode> errorNode = new ArrayList<>();
        //存储脏数据
        for (Map.Entry<Integer, ?> entry : nodeMap.entrySet()) {
            // 获取当前节点
            BaseTreeNode curNode =(BaseTreeNode) entry.getValue();
            // 获取到当前节点的父节点
            BaseTreeNode pNode = nodeMap.get(curNode.getPid());
            // 顶级节点加入树集合
            if (curNode.getMid().equals(nodeId)) {
                node = (curNode);
                continue;
            }
            // 没有父节点的脏数据,pid又不是0
            if (pNode == null) {
                errorNode.add(curNode);
                continue;
            }
            if (pNode.getChildren() == null) {
                pNode.setChildren(new ArrayList<>());
            }
            pNode.getChildren().add(curNode);
        }
        return (T)node;
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值