`
sunnylocus
  • 浏览: 875692 次
  • 性别: Icon_minigender_1
  • 来自: 美国图森
社区版块
存档分类
最新评论

递归显示数据库目录树(html+java servlet)

    博客分类:
  • Java
阅读更多

       应客户的要求,需要在定位平台上加多级部门的支持,可以无限分级,并将数据库中的部门及该部门下定位终端以目录树形式的显示在界面上,以数据库 目录树为关键字google了下,有参考价值的不多,大部门都是简单的显示下,格式也没有作缩进,很难看,客户肯定不满意,只能自己作了。要实现目录树肯定要用递归算法了。

      要实现递归,必须得有一个父节点作为参考,如果原来的表里是没有这个字段,就给加上。看下部门表和终端表的结构

 

部门表(group_info)

字段名                类型            说明

 -------------------------------------------------------------

 group_id                  number(10)         部门id (PK)          

 group_name            varchar2(20)       部门名称

 enterprise_id           number(10)         企业id

 upper_group_id       number(10)        上级部门id

 

终端表(locphone_list)

字段名                类型                     说明

-------------------------------------------------------------

 loc_phone            varchar2(11)    手机号码 (PK)

 loc_name             varchar2(50)    持有者姓名

 group_id              number(10)       所属部门id

 enterprise_id         number(10)      所属企业id

 

给这两个表分别插入测试数据

部门表

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (42, '技术部', 1, -1);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (1, '市场部', 1, -1);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6062, '软件开发部', 1, 42);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6063, '软件测评部', 1, 42);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6065, '定位系统开发', 1, 6062);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6066, '联通平台开发', 1, 6065);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (5702, '综合部', 1, -1);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6064, '渔业软件', 1, 6062);

insert into group_info (GROUP_ID, GROUP_NAME, ENTERPRISE_ID, UPPER_GROUP_ID)
values (6067, '电信平台开发', 1, 6065); 

终端表

 

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953415825', '小新', 42, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953645806', '小千', 6065, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953113253', '小波', 1, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318342218', '晓明', 6067, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953115549', '小朱', 5702, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('13335156298', '小李', 1, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318801656', '小徐', 42, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318803328', '小杨', 42, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953114426', '小玉', 6062, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318801259', '小程', 6062, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318805370', '张伟阳', 42, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('18953115808', '薛涛', 1, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('15318801313', '张培培', 1, 1);

insert into locphone_list (LOC_PHONE, LOC_NAME, GROUP_ID, ENTERPRISE_ID)
values ('13075306374', 'GPS_SMS', 42, 1); 

   用myeclipse新建一个项目取名为TreeShow,建一个数据库工具类,一个生成目录树的servlet,及一个用于显示的目录树的html,并在WebRoot目录下新建一个images文件夹将用到的图片拷贝到images文件夹

1、数据库工具类

 

package com.tdt.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public final class JdbcUtil {
	private static String url = "jdbc:oracle:thin:@localhost:1521:orcl_db";
	private static String user = "zwy";
	private static String password = "zwy";
	private JdbcUtil() {
	}
	static {
		try {
			Class.forName("oracle.jdbc.driver.OracleDriver");
		} catch (ClassNotFoundException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	//获取数据库连接对象
	public static Connection getConnection() {
		try {
			return DriverManager.getConnection(url, user, password);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}

	/**
	 * 关闭数据库连接
	 * @param st
	 * @param rs
	 * @param conn
	 */
	public static void free(Statement st, ResultSet rs, Connection conn) {
		try {
			if (st != null) st.close();
			if (rs != null) rs.close();
			if (conn != null) conn.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

 2、生成目录树的servlet

package com.tdt.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

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

import com.tdt.util.JdbcUtil;

public class ShowTerminalTreeServlet extends HttpServlet {
	private PrintWriter out;
	private String sql="";
	int divcode = 0;
	int enterprise_id = 0;
	String groupId="";
	private static Connection conn = JdbcUtil.getConnection();

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

		this.doPost(request, response);
	}
	
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		enterprise_id = 1;//Integer.parseInt((String)request.getSession().getAttribute("enterpriseid")); 这个地方应从登陆者的session获取企业id,为了方便查看效果直接赋值
		response.setContentType("text/html;charset=utf-8");
		out = response.getWriter();
		try {
			out.println("<img src='images/nolines_plus.gif' onclick='changeState(this,0)'><img src='images/base.png' />全部终端"
							+ "<div id=level0 style='display:none' >");
			generateTree(-1, 0);//从根部门向下查找,根部门的group_id为 -1
			out.println("</div>");
			out.flush();
			out.close();
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	// 产生树结构
	public void generateTree(int parentid, int level) throws SQLException {
		level++;
		divcode++;
		// Statement和ResultSet不要声明为全局变量,如果声明全局变量有可能会出现结果集耗尽
		Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
		sql ="select * from zwy.group_info where upper_group_id="+ parentid + " and enterprise_id =" + enterprise_id;
		ResultSet rs = st.executeQuery(sql);
		while (rs.next()) {
			for (int i = 0; i < level - 1; i++) { // 控制缩进
				out.print("<img src='images/line.gif' />");
			}
			
			int groupId =rs.getInt("group_id"); 
			String groupName = rs.getString("group_name");
			
			if ((existedChild(groupId) || existedTerminal(groupId))
					&& rs.isLast()) {// 有下级部门或着在该部门中有终端,并且是最后一行
				out.print("<img src='images/plusbottom.gif' onclick='changeState(this,"+ divcode+ ")' />"+ groupName+ "<br />");
			} else if ((existedChild(groupId) || existedTerminal(groupId))
					&& !rs.isLast()) {
				out	.print("<img src='images/plus.gif' onclick='changeState(this,"+ divcode+ ")' />"+ groupName+ "<br />");
			} else if (!existedChild(groupId)&& !existedTerminal(groupId) && rs.isLast()) {// 没有下级部门也没有终端,且是最后一行
				out.print("<img src='images/joinbottom.gif' onclick='changeState(this,"+ divcode+ ")' />"+ groupName+ "<br />");
			} else {
				out.print("<img src='images/join.gif' onclick='changeState(this,"+ divcode+ ")' />"+ groupName+ "<br />");
			}

			// 获得该部门下的所有终端
			List<String[]> terminalList = getTerminalByGroup(group_id);
			out.println("<div id='level" + divcode+ "' style='display:none;'>\n");
			for (int x = 0; x < terminalList.size(); x++) {
				if (!rs.isLast()) {
					for (int i = 0; i < level; i++) { 
						out.print("<img src='images/line.gif' />");
					}
				} else if (x == (terminalList.size() - 1)) {// 最后一个终端
					for (int i = 0; i < level - 1; i++) { 
						out.print("<img src='images/line.gif' />");
					}
					out.print("<img src='images/empty.gif' />");
				} else {
					for (int i = 0; i < level; i++) { 
						out.print("<img src='images/empty.gif' />");
					}
				}//上面的代码用于控制格式缩进
				if (x != (terminalList.size() - 1)) {
					out.println("<img src='images/join.gif' />"+terminalList.get(x)[1] +"<br />");
				} else {// 最后一个终端
					//判断是否还有下级
					 if(existedChild(groupId)) {
						 out.println("<img src='images/join.gif' />"+terminalList.get(x)[1] +"<br />");
					 } else {
						 out.println("<img src='images/joinbottom.gif' />"+terminalList.get(x)[1] +"<br />");
					 }
				}
			}
			generateTree(groupId, level); // 递归调用,虽然又调用了函数generateTree,但是在概念上,我们应该把
					           // 它当作另外一个函数,每次当我们调用一个函数的时候--无论是递归调用
					           // 还是非递归调用,该函数都会得到自己独有的一组局部变量和形式变量
			out.println("</div>");
		}
		JdbcUtil.free(st, rs, null);
	}

	// 检查是否有下级部门
	public boolean existedChild(int groupid) throws SQLException {
		Statement st = null;
		ResultSet rs = null;
		st = conn.createStatement();
		sql = "select * from zwy.group_info where upper_group_id=" + groupid
				+ " and enterprise_id=" + enterprise_id;
		rs = st.executeQuery(sql);
		boolean flag = rs.next();
		JdbcUtil.free(st, rs, null);
		return flag;
	}

	// 检查该部门中是否有终端
	public boolean existedTerminal(int groupid) throws SQLException {
		Statement st = null;
		ResultSet rs = null;
		st = conn.createStatement();
		
		sql = "select * from zwy.locphone_list where group_id=" + groupid
				+ "  and enterprise_id=" + enterprise_id;
		rs = st.executeQuery(sql);
		boolean flag = rs.next();
		JdbcUtil.free(st, rs, null);
		return flag;
	}

	// 获取该部门所有的终端
	public List<String[]> getTerminalByGroup(int groupid) throws SQLException {
		Statement st = null;
		ResultSet rs = null;
		List<String[]> terminalList = null;
		st = conn.createStatement();
		sql = "select * from zwy.locphone_list where group_id=" + groupid
				+ " and enterprise_id=" + enterprise_id;
		rs = st.executeQuery(sql);
		terminalList = new ArrayList<String[]>();
		while (rs.next()) {
			String[] args = new String[2];
			args[0] = rs.getString("LOC_PHONE");
			args[1] = rs.getString("LOC_NAME");
			terminalList.add(args);
		}
		JdbcUtil.free(st, rs, null);
		return terminalList;
	}
	
	public void destroy() {
		//当servlet被销毁时,才关闭数据库的连接
		JdbcUtil.free(null, null, conn);
	}
}

 

3、显示目录树的index.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<style type="text/css">
	body {
		font-family: Verdana, Geneva, Arial, Helvetica, sans-serif;
		color: #666;
		font-size: 13px;
		white-space: nowrap;
	}
	img {
		border: 0px;
		vertical-align: middle;
	}  
	#idshowTree input {  //如果要在终端或着部门前面加上checkbox以便得到相应的值的话,最好能加上这样的格式。如果checkbox的size比line.gif图片的size大的话,左边控制缩进的坚线会有空白
		width: 13px;
		height: 13px;
		margin-right: 3px;
		
	}
	</style>
<script type="text/javascript">
  	var xmlhttpReq;
	//用于创建XMLHttpRequest对象
	function createXmlHttp() {
	    //根据window.XMLHttpRequest对象是否存在使用不同的创建方式
	    if (window.XMLHttpRequest) {
	       xmlhttpReq = new XMLHttpRequest();                  //FireFox、Opera等浏览器支持的创建方式
	    } else {
	       xmlhttpReq = new ActiveXObject("Microsoft.XMLHTTP");//IE浏览器支持的创建方式
	    }
	}
  	//动态显示+、-号图片
  	function changeState(oDiv,iDivcode){
		 var object = document.getElementById("level"+iDivcode);
		 if(object.style.display=='none'){
			  object.style.display='block';
		 }else{
			  object.style.display='none';
		 }
		 if(oDiv.src.indexOf("images/minus.gif")>0) {
		 	oDiv.src="images/plus.gif";
		 }else if (oDiv.src.indexOf("images/plus.gif")>0) {
		 	oDiv.src="images/minus.gif";
		 }else if(oDiv.src.indexOf("images/minusbottom.gif")>0) {
		 	oDiv.src="images/plusbottom.gif";
		 }else if(oDiv.src.indexOf("images/plusbottom.gif")>0) {
		 	oDiv.src="images/minusbottom.gif";
		 }else if(oDiv.src.indexOf("images/nolines_plus.gif")>0) {
		 	oDiv.src="images/nolines_minus.gif";
		 }else if(oDiv.src.indexOf("images/nolines_minus.gif")>0){
		 	oDiv.src="images/nolines_plus.gif";
		 }
    }
  
  function initpage() {
  	createXmlHttp();
	xmlhttpReq.open("GET","ShowTerminalTreeServlet?"+new Date().getTime(),true);
	xmlhttpReq.send(null);
  	xmlhttpReq.onreadystatechange=function(){
	 if(xmlhttpReq.status == 200) {
	 	if(xmlhttpReq.readyState == 4) {
	 		var info =xmlhttpReq.responseText;
	 		$("idshowTree").innerHTML=info;
	 	}
	  }
	}
  }
  
  function $(id) {
  	return document.getElementById(id);
  }
</script>
</head>

<body onload="initpage()">
	<div id="idshowTree" >
	</div>
</body>
</html>

4.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" 
	xmlns="http://java.sun.com/xml/ns/j2ee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
	http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  <servlet>
    <servlet-name>ShowTerminalTreeServlet</servlet-name>
    <servlet-class>com.tdt.servlet.ShowTerminalTreeServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>ShowTerminalTreeServlet</servlet-name>
    <url-pattern>/ShowTerminalTreeServlet</url-pattern>
  </servlet-mapping>

  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>
</web-app>

 

 访问http://localhost:8080/TreeShow就能看到效果了

需要注意的问题:

    1、不要将Statement和ResultSet声明为全局变量,如果声明为全局变量你会发现前几次会正常显示,多次刷新index.html会出现结果集耗尽的情况,导致index.html页面不会显示任何的内容

    2、不要将获取数据库连接的语句放在generateTree()方法内,如果放到generateTree()方法内,那么每次递归调用generateTree()就连一次数据库,连接数据库是非常耗时的工作,根据TCP/IP 协议需要进行三次握手后才能建立连接,如果数据库服务器不在同一个局域网的话连接的时间会更长。在csdn看到有的朋友问为什么我递归显示数据库数据非常慢,就是这个原因造成的。

    3、最好将Connection声明为static成员变量并赋值,使用完后不要关闭连接。这样另外一个人访问时就不需要再建立与数据库的连接,提高速度。要作的更好的话,将赋值语句放在servlet的init()方法内,然后再在web.xml指定load-on-startup,web容器一启动就完成数据库的连接。如果是使用数据库连接池就另说了。

 

 我的测试环境为tomcat6.0+oracle 10g+J2EE1.4

 

 图片我打包上传,代码都已经贴出来了。有需要的朋友留下邮箱,我会把完整的项目发到邮箱里。

 

 

 

 

7
0
分享到:
评论
9 楼 suipian1029 2015-04-20  
求源码 839550558@qq.com
8 楼 abc3720 2013-08-09  
求份源码 372049596@qq.com
7 楼 sunnylocus 2011-10-18  
黄俊IT 写道
楼主,您好!本人想分享楼主的目录树源码,邮箱: huangjunit@163.com  谢谢咯!

代码没有了,好长时间了。不过所有的代码我已经贴到上面了,你新建个web工程把文章里的代码扒下来放到新建个工程里,运行下效果就可以了。哎,我应该把代码上传上来的
6 楼 黄俊IT 2011-10-17  
楼主,您好!本人想分享楼主的目录树源码,邮箱: huangjunit@163.com  谢谢咯!
5 楼 wangfeiaini 2011-10-04  
楼主,给发个完整的项目吧。邮箱:wind19880625@163.com
4 楼 023photon 2011-05-25  
把楼主代码扒下来自己创建工程、数据库,运行成功了,初看还以为点击“加号”是Ajax异步读取数据,运行程序仔细一看,不是,有点失望。

我数据库用的sql server 2005,其他基本一样的,代码里有个地方貌似有问题——List<String[]> terminalList = getTerminalByGroup(groupId); 这行把“group_id”改成“groupId”才编译通过,效果跟楼主贴的效果图不一样,因为数据不全一样。另外就是有个地方显示不完整,如图:




“小千”前面本该显示一条竖线的,但没有,可以说是一个小问题。总的来说,还是不错,功能虽没有zTree那么多,但界面很简洁,清爽。
3 楼 sunnylocus 2011-01-24  
lxtkong-029 写道
您好,麻烦你给我发一份目录树的源码,谢谢,邮箱:lxtkong-029@163.com,邮箱开头的字母不是一啊,呵呵

不好意思,这个是我做验证时写的,时间好久了,代码找不到了,其实除了JdbcUtil类没有贴出来,其它的都贴出来了,你在Myeclipse里建立工程把代码贴进去,然后把JdbcUtil类getConnection方法和free方法实现就可以了
2 楼 lxtkong-029 2011-01-24  
您好,麻烦你给我发一份目录树的源码,谢谢,邮箱:lxtkong-029@163.com,邮箱开头的字母不是一啊,呵呵
1 楼 miansoon 2010-12-02  
想分享楼主目录树源码,邮箱:miansoon@163.com .谢谢。

相关推荐

    树形目录的递归实现数据库

    ### 树形目录的递归实现数据库 #### 数据库结构设计与实现原理 根据所提供的信息,我们可以了解到,这里讨论的是如何使用 Java 和 JSP 实现一个树形目录系统,并将其存储在数据库中。该系统主要涉及到数据库的设计...

    ajax + div +js +xml+ servlet 实现无限级动态目录树(原创)

    在这个项目中,每个目录节点通常会被表示为一个`&lt;div&gt;`,通过CSS样式进行美化,并通过JavaScript操作其显示与隐藏,以实现目录树的展开与折叠效果。 **JavaScript**: JavaScript是实现动态目录树的关键,它负责...

    无限级树(Java递归)

    ### 无限级树(Java递归)知识点解析 #### 一、概述 本文将深入解析一个基于Java实现的无限级树形结构,并采用递归方式构建。该树形结构主要用于展示具有层级关系的数据,例如网站分类目录等。通过递归查询数据库中...

    使用递归方式的easyUI Servlet 异步加载树

    在本场景中,我们将探讨如何利用递归、easyUI和Servlet来实现异步加载树形结构的数据。EasyUI是一个基于jQuery的前端框架,提供丰富的组件,包括我们这里提到的树形控件。而Servlet是Java Web开发中的服务器端组件,...

    [其他类别]JSP无限级分类目录树_sorttree.zip

    3. 递归:实现无限级目录树的关键是递归算法,用于遍历和显示层次结构。 4. Java Servlet:JSP背后的执行引擎就是Servlet,它们一起处理HTTP请求并生成响应。 5. DOM(Document Object Model):如果涉及到HTML生成...

    JSP无限级分类目录树

    总的来说,JSP无限级分类目录树技术涉及了JSP、Java后端处理、数据库操作、递归算法以及前端展示等多个方面,是Web开发中的重要技能之一。通过导入给定的项目,开发者可以直接体验和学习这一技术的实现细节。

    JSP无限级分类目录树_sorttree.rar

    【JSP无限级分类目录树_sorttree.rar】这个压缩包文件是针对计算机毕业设计的一份实践资源,主要涉及的技术领域包括计算机网络、毕业设计、JSP(Java Server Pages)以及JAVA语言。在这个项目中,开发者将学习如何...

    [其他类别]JSP无限级分类目录树_sorttree(毕设 + 课设).zip

    无限级分类目录树的核心在于递归算法的应用,它能够在运行时根据数据库中的数据自动生成任意深度的树形结构。在这个实现中,`SortTree`可能是用来表示目录树结构的类,包含节点的添加、删除、展开、折叠等操作。而`...

    JSP+javaBean+数据库 无限级动态树状菜单

    例如,`Tree.java`可能包含了根据数据库数据生成树结构的方法,而`Cn.java`可能用于处理数据库的CRUD(创建、读取、更新、删除)操作。 3. **数据库**: 数据库是存储和管理数据的系统,本项目中使用的数据库未...

    JSP无限级分类目录树.zip

    - 构建无限级分类目录树的关键在于使用递归算法。通过查询数据库获取所有类别,然后根据每个类别的父ID进行递归调用,生成树形结构。 4. **JSP和Servlet** - JSP主要用于视图层的展示,而Servlet则处理业务逻辑。...

    JSP无限级分类目录树-sorttree.rar

    3. **Servlet处理请求**:当用户请求目录树时,Servlet负责从数据库中查询所有分类,通过递归或者迭代方式构建树形结构。这个过程中,可能需要用到`Map`或`List`数据结构来辅助表示层级关系。 4. **无限级分类算法*...

    学校实训JSP项目-[其他类别]JSP无限级分类目录树.zip

    在这个“学校实训JSP项目-[其他类别]JSP无限级分类目录树.zip”中,我们主要探讨的是如何在JavaServer Pages (JSP) 中实现一个能够处理无限级分类目录树的功能。这个实训项目可能适用于高校学生的课程设计或者毕业实...

    java web下开发二级级联下拉菜单(数据库实现的)

    总之,通过结合Java Web技术和数据库,我们可以实现动态的二级级联下拉菜单,为用户提供直观且易于操作的界面。这个过程涉及到数据库设计、后端服务开发以及前端交互等多个环节,对提升开发者综合能力非常有帮助。

    JSP无限级分类目录树-sorttree.zip

    总之,“JSP无限级分类目录树_sorttree.zip”是一个关于Java Web开发的实践案例,涵盖了数据模型、数据库操作、JSP页面渲染等多个方面,对于学习和掌握动态生成无限级分类目录树的技能非常有帮助。通过这个项目,...

    基于JSP实现的无限级分类目录树

    总的来说,"基于JSP实现的无限级分类目录树"项目涵盖了后端数据库设计、Java编程、JSP动态页面渲染、前端JavaScript交互等多个方面,对于学习Java Web开发的初学者和进阶者来说,这是一个很好的实践项目,能够帮助...

    [其他类别]JSP无限级分类目录树_sorttree.rar

    【标题】:“JSP无限级分类目录树_sorttree”是一个基于...综上所述,"JSP无限级分类目录树_sorttree"是一个综合运用了Java、JSP、Servlet、数据库操作等技术的Web应用,其目的是提供一个高效、灵活的分类管理系统。

Global site tag (gtag.js) - Google Analytics