实现web树

作者: 小小蒜头 | 来源:发表于2017-10-11 19:31 被阅读52次

像在淘宝、京东等网站上都会有树状分类,而要实现这种结构(web树),就要在数据库里有张表保存分类数据。

对于下图中结构的分类:

结构

就要采用下图中的方式,比如我要找出商品下的所有分类,就只需要找出在商品左支和右支之间的所有节点就行了。

方法

树状节点的特点:

  1. 每一个节点都有一个左右值。
  2. 如果右值-左值=1,则代表当前节点为叶子节点。
  3. 如果右值-左值>1,则代表当前节点有孩子节点,值在左右值之间的所有节点,即为当前结点的所有孩子节点。

数据库表设计:

数据库表设计:
create table category
(
    id varchar(40) primary key,
    name varchar(100),
    lft int,
    rgt int
);
insert into category values('1','商品',1,18);
insert into category values('2','平板电视',2,7);
insert into category values('3','冰箱',8,11);
insert into category values('4','笔记本',12,17);
insert into category values('5','长虹',3,4);
insert into category values('6','索尼',5,6);
insert into category values('7','西门子',9,10);
insert into category values('8','thinkpad',13,14);
insert into category values('9','dell',15,16);

结果如图所示:

效果预览

问题:为了在页面中显示树状结构,需要得到所有结点,以及每个结点在树中的层次。

解决思路:

1、 要得到结点的层次,就是看节点有几个父亲,例如长虹有2个父亲,则它所在层次就为2。

2、 如何知道每一个节点有几个父亲呢?这个表有个特点,父亲和孩子都在同一个表中,为得到父亲所有的孩子,可以把这张表想像成两张表,一张用于保存父亲,一张表保存孩子,如下所示:
select * from category parent,category child;
3、 父亲下面的孩子有个特点,它的左值>父亲的左值,并且<父亲的右值,如下所示
select * from category parent,category child where child.lft>=parent.lft and child.rgt<=parent.rgt;
以上语句会得到父亲下面所有的孩子。

4、 对父亲所有孩子的姓名进行归组,然后使用count统计函数,这时就会知道合并了几个孩子,合并了几个孩子姓名,这个孩子就有几个父亲,从而知道它所在的层次
select child.name,count(child.name) depth from category parent,category child where child.lft>=parent.lft and child.rgt<=parent.rgt group by child.name;

5、 最后根据左值排序即可
select child.name,count(child.name) depth from category parent,category child where child.lft>=parent.lft and child.rgt<=parent.rgt group by child.name order by child.lft;

代码展示:

1. 实体类Category

package cn.itcast.domain;

/**
 * Created by yvettee on 2017/10/10.
 */
public class Category {
    private String id;
    private String name;
    private int lft;
    private int rgt;
    private int depth;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getLft() {
        return lft;
    }

    public void setLft(int lft) {
        this.lft = lft;
    }

    public int getRgt() {
        return rgt;
    }

    public void setRgt(int rgt) {
        this.rgt = rgt;
    }

    public int getDepth() {
        return depth;
    }

    public void setDepth(int depth) {
        this.depth = depth;
    }
}

2. 具体实现类CategoryDao

package cn.itcast.dao;

import cn.itcast.domain.Category;
import cn.itcast.utils.JdbcUtils_dbcp;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.util.List;

/**
 * Created by yvettee on 2017/10/10.
 */
public class CategoryDao {
    public List<Category> getAll() {
        try {
            QueryRunner runner = new QueryRunner(JdbcUtils_dbcp.getDataSource());
            String sql = "select child.id,child.name,child.lft,child.rgt,count(child.name) depth from category parent,category child where child.lft>=parent.lft and child.rgt<=parent.rgt group by(child.name) order by child.lft;";
            List list = runner.query(sql, new BeanListHandler<Category>(Category.class));
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

3. 业务层BusinessService

package cn.itcast.service;

import cn.itcast.dao.CategoryDao;

import java.util.List;

/**
 * Created by yvettee on 2017/10/10.
 */
public class BusinessService {
    public List getAllCategory() {
        CategoryDao dao = new CategoryDao();
        return dao.getAll();
    }
}

4. ListTreeServlet,要跳转到jsp页面进行显示

package cn.itcast.web;

import cn.itcast.service.BusinessService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * Created by yvettee on 2017/10/10.
 */
@WebServlet(name = "ListTreeServlet", urlPatterns = "/listTreeServlet")
public class ListTreeServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        BusinessService service = new BusinessService();
        List list = service.getAllCategory();
        request.setAttribute("list", list);
        request.getRequestDispatcher("/listTree.jsp").forward(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

5. listTree.jsp,在本页面要用${list}取出数据进行一棵树的显示,没必要自己写js代码,有很多现成的控件,比如xtree,在xtree里的index.html中的Usage中有示例

树状结构由JS生成的

只需要将用到的js与css导入。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>ListTree</title>
    <script src="${pageContext.request.contextPath }/js/xtree.js"></script>
    <link type="text/css" rel="stylesheet" href="${pageContext.request.contextPath }/css/xtree.css">
</head>
<body>
<script type="text/javascript">
    <c:forEach var="c" items="${list}">
    <c:if test='${c.depth==1 }'>
    var tree = new WebFXTree('${c.name}');
    </c:if>

    <c:if test='${c.depth==2 }'>
    var node${c.depth} = new WebFXTreeItem('${c.name}');   //node2
    tree.add(node${c.depth});
    </c:if>

    <c:if test='${c.depth>2 }'>
    var node${c.depth} = new WebFXTreeItem('${c.name}');  //node3
    node${c.depth-1}.add(node${c.depth});    //
    </c:if>
    </c:forEach>
    document.write(tree);
</script>
</body>
</html>

源代码:https://github.com/yvettee36/WebTree

相关文章

  • 实现web树

    像在淘宝、京东等网站上都会有树状分类,而要实现这种结构(web树),就要在数据库里有张表保存分类数据。 对于下图中...

  • http url router设计

    看了go web领域的httprouter实现借用了radix tree这个树,据介绍路由效率很高,而且还很省内存...

  • 年薪20万Python工程师进阶(3):Python开发之理解W

    本文目录 什么是WSGI? 如何实现Application? 如何实现Web Server? Web Server...

  • web后端技术树

    web后端技术树

  • Web开发树

    认知篇我的编程观必备一张成长路径图,并周期性地更新它编程就是为了解决问题优秀的代码组织风格,更便于维护 环境与工具...

  • 一行代码启动 Web server

    一行代码启动 Web server 实现   Python3 实现:   NodeJS 实现: NodeJS 实现...

  • Android Webview 实现input type="fi

    一、引言 Android webview是不会默认实现web里的 的选择文件功能,要想实现web的选择文件功能需要...

  • Flutter Mall Web——1启动页

    上一篇文章进行了Flutter Web项目的体验,接下来将会实现商城的web端。 首先来实现启动页,web启用图片...

  • HTTP学习笔记

    Web 页面的实现 Web 基于 HTTP 协议通信 客户端(Client)的 Web 浏览器从 Web 服务器端...

  • web上用户登录功能

    实现Web上的用户登录功能 关于如何实现web上的自动登录功能文章来源http://coolshell.cn/ar...

网友评论

    本文标题:实现web树

    本文链接:https://www.haomeiwen.com/subject/hvbbyxtx.html