Java 实现树形结构

       树形结构可以清楚地呈现数据的从属关系,在数据库中我们可以用自关联来保存这样的关系。但是在取出数据的时候,如果采用以往的手段,免不了要进行递归操作。递归在理论上是可以解决树形结构的问题,但是如果数据量够大,目录层次够深,我们递归出层次关系是比较消耗资源的。我们可以从数据结构入手,树有它的分支,每个分支又可以延伸出新的分支,那么我们可以在每个节点中增加它的左支和右支,左支和右支良好的维护了树形体系。父节点的左支是永远小于子节点的左支,父节点的右支是永远大于子节点的右支,有了这样的关系,我们想要表现出树形结构是很简单的。所以我们将数据库表设计为自关联表,每个记录中都维护着一个坐支和右支。不必在表中添加父节点列也可以轻松搞定树状关系。

效果图:

 

 

Dao层

package cn.dk.dao;

import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.dk.domain.Category;
import cn.dk.utils.JdbcUtils;

public class CategoryDao {

	@SuppressWarnings("unchecked")
	public List<Category> selectAllCategory() {
		QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
		String sql = "select c.id,c.name,c.left_hand,c.right_hand,count(c.name) depth from category p,category c where p.left_hand<=c.left_hand and p.right_hand>=c.right_hand group by c.name order by c.left_hand";
		try {
			return (List<Category>) runner.query(sql, new BeanListHandler(
					Category.class));
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public Category selectCategory(String id) {
		QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
		String sql = "select id,name,left_hand,right_hand from category where id=?";
		Object[] params = { id };
		try {
			return (Category) runner.query(sql,
					new BeanHandler(Category.class), params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public void insertCategory(Category category) {
		QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
		String sql = "insert into category values(?,?,?,?)";
		Object[] params = { category.getId(), category.getName(),
				category.getLeft_hand(), category.getRight_hand() };
		try {
			runner.update(sql, params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	@SuppressWarnings("unchecked")
	public List<Category> selectParent(String id) {
		QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
		String sql = "select p.id,p.name,p.left_hand,p.right_hand from category p,category c where p.left_hand <= c.left_hand and p.right_hand >= c.right_hand and c.id=? order by p.left_hand";
		Object[] params = { id };
		try {
			return (List<Category>) runner.query(sql, new BeanListHandler(
					Category.class), params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	public void updateCategory(int left_hand) {
		String sql = "update category set left_hand=left_hand+2 where left_hand>? ";
		QueryRunner runner = new QueryRunner(JdbcUtils.getDataSource());
		try {
			runner.update(sql, left_hand);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
		sql = "update category set right_hand=right_hand+2 where right_hand>=? ";
		try {
			runner.update(sql, left_hand);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}


Service 层

package cn.dk.service;

import java.util.List;
import java.util.UUID;

import cn.dk.dao.CategoryDao;
import cn.dk.domain.Category;

public class CategoryService {

	public List<Category> selectAllCategory(){
		CategoryDao categoryDao = new CategoryDao();
		return categoryDao.selectAllCategory();
	}
	
	public List<Category> selectParents(String id){
		CategoryDao categoryDao = new CategoryDao();
		return categoryDao.selectParent(id);
	}
	
	public void insertCategory(String name, String parentId){
		CategoryDao categoryDao = new CategoryDao();
		Category parent = categoryDao.selectCategory(parentId);
		
		Category child = new Category();
		child.setId(UUID.randomUUID().toString());
		child.setName(name);
		child.setLeft_hand(parent.getRight_hand());
		child.setRight_hand(parent.getRight_hand() + 1);
		
		categoryDao.updateCategory(child.getLeft_hand());
		categoryDao.insertCategory(child);
	}
}

 

Web 层

package cn.dk.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.dk.service.CategoryService;

@SuppressWarnings("serial")
public class InsertCategoryServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		String id = request.getParameter("id");
		String name = request.getParameter("name");
		CategoryService serivice = new CategoryService();
		serivice.insertCategory(name, id);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}

 
package cn.dk.web;

import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.dk.domain.Category;
import cn.dk.service.CategoryService;

@SuppressWarnings("serial")
public class SelectAllCategoryServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		CategoryService service = new CategoryService();
		List<Category> cList = service.selectAllCategory();
		request.setAttribute("category", cList);
		request.getRequestDispatcher("/WEB-INF/pages/showList.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

package cn.dk.web;

import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.dk.domain.Category;
import cn.dk.service.CategoryService;

@SuppressWarnings("serial")
public class ShowInsertServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		CategoryService service = new CategoryService();
		String id = request.getParameter("id");
		List<Category> parent = service.selectParents(id);
		request.setAttribute("parent", parent);
		request.setAttribute("id", id);
		request.getRequestDispatcher("/WEB-INF/pages/insert.jsp").forward(request,
				response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}


Jsp

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  	<script type="text/javascript" src="${pageContext.request.contextPath }/js/xtree.js"></script>
  	<link type="text/css" href="${pageContext.request.contextPath }/css/xtree.css">
  </head>
  
  <body>
  	<script type="text/javascript">
  		<c:forEach var="ctg" items="${requestScope.category}">
	  		<c:if test="${ctg.depth==1}">
	  			var root = new WebFXTree('${ctg.name }');
	  			root.setBehavior('explorer');
	  			root.action="${pageContext.request.contextPath}/servlet/ShowInsertServlet?id=${ctg.id}";
	  			root.target="main";
	  		</c:if>
			<c:if test="${ctg.depth==2}">
	  			var node${ctg.depth } = new WebFXTreeItem('${ctg.name }');
	  			node${ctg.depth}.action="${pageContext.request.contextPath}/servlet/ShowInsertServlet?id=${ctg.id}";
	  			node${ctg.depth}.target="main";
	  			root.add(node${ctg.depth });
	  		</c:if> 
	  		<c:if test="${ctg.depth>2}">
	  			var node${ctg.depth } = new WebFXTreeItem('${ctg.name }');
	  			node${ctg.depth}.action="${pageContext.request.contextPath}/servlet/ShowInsertServlet?id=${ctg.id}";
	  			node${ctg.depth}.target="main";
	  			node${ctg.depth-1 }.add(node${ctg.depth });
	  		</c:if>  		
  		</c:forEach>
  		document.write(root);
  	</script>
  </body>
</html>
 
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
  </head>
  
  <body>
    <br><br>
    您当前的位置 : 
    <c:forEach var="p" items="${requestScope.parent}" >
    	${p.name }>>>
    </c:forEach>
    <form action="${pageContext.request.contextPath }/servlet/InsertCategoryServlet?id=${requestScope.id }" method="post">
    	<input type="text" name="name" >
    	<input type="submit" value="增加节点">
    </form>	
  </body>
</html>


 

 




  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 21
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值