LayUi之树形结构的详解(附有全案例代码)

news2024/10/6 12:31:34

🥳🥳Welcome Huihui's Code World ! !🥳🥳

接下来看看由辉辉所写的关于LayUi的相关操作吧

目录

🥳🥳Welcome Huihui's Code World ! !🥳🥳

一. 什么是树形结构

二.树形结构在什么时候使用(常见使用场景)

三.怎么完成树形结构中的数据交互 (思路)

1. 设计数据库表结构:

2. 插入数据:

3. 查询数据:

4. 处理层级关系:

5.编写servlet

6.jsp界面接收数据

7.最终效果展示

四.详细案例解析

实现效果

思路

表结构

实体类

工具类

配置文件

公共页面(引入的文件)

jsp界面

dao

servlet


上篇我们已经对LayUi有了一个基本的了解,并且使用它做出了两个简单的小案例,那么本篇,我们就来看看它其中的动态树组件吧!

其中还是有用到自定义mvc框架,不懂的小伙伴可以点击下方链接查看
自定义MVC框架【上篇】icon-default.png?t=N658http://t.csdn.cn/giVlE

自定义MVC框架【中篇】--框架实现icon-default.png?t=N658http:// http://t.csdn.cn/ul7Eu
自定义MVC框架【下篇】--运用框架完成增删改查icon-default.png?t=N658http://t.csdn.cn/RHgke

一. 什么是树形结构

  • 树形结构是一种层次化的数据结构,采用分层的方式来组织和表示数据。它由节点(node)和边(edge)组成,节点代表数据的存储单元,边代表节点之间的关系
    • 树形结构中有一个根节点(root),它是整个树的起点,根节点可以有多个子节点(child node),每个子节点又可以有自己的子节点,如此递归下去,形成树状的结构。每个节点可以有任意数量的子节点,但一个节点只有一个父节点(除了根节点)。没有子节点的节点被称为叶节点(leaf node),而有子节点的节点称为内部节点
    • 树形结构可以用来表示各种实际问题,如文件系统的目录结构、组织机构的层级关系等。它具有良好的扩展性和灵活性,在查找、插入和删除等操作上具有较高的效率

二.树形结构在什么时候使用(常见使用场景)

  • 1. 文件系统:操作系统中的文件系统通常使用树形结构来组织文件和目录的层次关系。每个目录可以包含多个子目录和文件,形成一棵文件树
  • 2. 组织机构:组织机构中的层级关系常常可以使用树形结构来表示,如企业组织结构、学校院系结构等。每个部门或学院可以有多个子部门或学系,形成组织机构的分层关系
  • 3. 数据分类和分类索引:树形结构可以用于对数据进行分类和分类索引,如图书分类系统、商品分类系统等。每个分类可以有多个子分类,构建出数据的层级分类结构,方便数据的管理和检索
  • 4. XML和HTML文档:XML和HTML文档中的标签元素可以形成树形结构的层次关系,通过父子关系来表示不同元素之间的层级关系
  • 5. 数据库索引:数据库中的索引可以使用树形结构来组织,如B树和B+树等索引结构。这些树形结构可以加速数据库的查询操作
  • 6. 算法和数据结构:许多常见的算法和数据结构都基于树形结构,如二叉树、AVL树、红黑树等。这些树形结构可用于高效地实现搜索、排序和存储等操作
  • 7. 路由和网络拓扑:网络中的路由和网络拓扑结构常常使用树形结构来表示,通过节点和边的关系来描述设备之间的连接和通信路径
  • 8. AI决策树和推荐系统:在人工智能领域,决策树被广泛应用于分类和预测问题,通过递归地划分特征空间来进行决策。推荐系统中也可以使用树形结构来组织用户和物品之间的关系

这些只是树形结构的一些常见使用场景,实际上,树形结构在很多领域都有着重要的应用价值,可以更好地组织和表示复杂的关系和层级结构

三.怎么完成树形结构中的数据交互 (思路)

  • 1. 设计数据库表结构:

    • 首先需要设计合适的数据库表结构来存储树形结构的数据。通常可以使用两种方法来表示树型结构的数据库表设计:邻接表模型和嵌套集模型。邻接表模型使用一张表,每行记录代表一个节点,通过一个外键来表示父节点与子节点之间的关系。嵌套集模型使用两个字段来表示每个节点的左右边界,通过这些边界值可以确定节点的子节点
  • 2. 插入数据:

    • 将树形结构的数据插入到数据库表中。可以按照规定的表结构,逐个节点地插入到相应的表中,确保每个节点的数据与其父节点正确关联
  • 3. 查询数据:

    • 可以使用SQL等查询语言来从数据库中获取树形结构的数据。根据具体的需求,可以使用递归查询、连接查询或者子查询等方式来获得树形结构中的节点及其关系
    • package com.wh.dao;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import com.wh.entity.Permission;
      import com.wh.entity.User;
      import com.zking.util.BaseDao;
      import com.zking.util.BuildTree;
      import com.zking.util.PageBean;
      import com.zking.util.TreeVo;
      
      public class PermissionDao extends BaseDao<Permission>{
      	//查询所有
      		public List<Permission> list( Permission permission, PageBean pageBean) throws Exception {
      	  String sql="select * from t_oa_permission";
      			return super.executeQuery(sql, Permission.class, pageBean);
      		}	
      }
      
  • 4. 处理层级关系:

    • 根据查询出来的数据,可以根据节点之间的层级关系来构建树形结构,并进行进一步的处理。可以使用编程语言中的数据结构或者自定义类来表示和操作树形结构
    • package com.wh.dao;
      
      import java.util.ArrayList;
      import java.util.List;
      
      import com.wh.entity.Permission;
      import com.wh.entity.User;
      import com.zking.util.BaseDao;
      import com.zking.util.BuildTree;
      import com.zking.util.PageBean;
      import com.zking.util.TreeVo;
      
      public class PermissionDao extends BaseDao<Permission>{
      	//将原数据转换成有层级关系的数据(借助自定义 工具类TreeVo完成)
      	public List<TreeVo<Permission>> menus( Permission permission, PageBean pageBean) throws Exception {
      		List<TreeVo<Permission>> menus = new ArrayList<>();
      		List<Permission> list = this.list(permission, pageBean);
      		for (Permission p : list) {
      			TreeVo<Permission> tv = new TreeVo<>();
      			tv.setId(p.getId()+"");
      			tv.setParentId(p.getPid()+"");
      			tv.setText(p.getName());
      			menus.add(tv);
      		}
      //		return menus;
      		return BuildTree.buildList(menus, "-1");//-1是顶级节点的id
      	}
      		
      		
      }
      
  • 5.编写servlet

    • package com.wh.web;
      
      import java.util.List;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      import com.wh.dao.PermissionDao;
      import com.wh.entity.Permission;
      import com.zking.framework.ActionSupport;
      import com.zking.framework.ModelDriver;
      import com.zking.util.PageBean;
      import com.zking.util.ResponseUtil;
      import com.zking.util.TreeVo;
      
      public class PermissionAction extends ActionSupport implements ModelDriver<Permission>{
      private Permission permission = new Permission();
      private PermissionDao pd = new PermissionDao();
      
      	public void menus(HttpServletRequest req, HttpServletResponse resp) {
      				try {
      					List<TreeVo<Permission>> menus = pd.menus(null, null);
      					ResponseUtil.writeJson(resp, menus);
      				} catch (Exception e) {
      					e.printStackTrace();
      				}
      	}
      	@Override
      	public Permission getModel() {
      		return permission;
      	}
      
      }
      
  • 6.jsp界面接收数据

    • <%@ page language="java" contentType="text/html; charset=UTF-8"
          pageEncoding="UTF-8"%>
      <!DOCTYPE>
      <html>
      <head>
        <%@include file="/common/head.jsp" %>
      </head>
      <body>
      <div class="layui-layout layui-layout-admin">
        <div class="layui-header">
          <div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
          <!-- 头部区域(可配合layui 已有的水平导航) -->
          <ul class="layui-nav layui-layout-left">
            <!-- 移动端显示 -->
            <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
              <i class="layui-icon layui-icon-spread-left"></i>
            </li>
            <!-- Top导航栏 -->
            <li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
            <li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
            <li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
            <li class="layui-nav-item">
              <a href="javascript:;">nav groups</a>
              <dl class="layui-nav-child">
                <dd><a href="">menu 11</a></dd>
                <dd><a href="">menu 22</a></dd>
                <dd><a href="">menu 33</a></dd>
              </dl>
            </li>
          </ul>
          <!-- 个人头像及账号操作 -->
          <ul class="layui-nav layui-layout-right">
            <li class="layui-nav-item layui-hide layui-show-md-inline-block">
              <a href="javascript:;">
                <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
                tester
              </a>
              <dl class="layui-nav-child">
                <dd><a href="">Your Profile</a></dd>
                <dd><a href="">Settings</a></dd>
                <dd><a href="login.jsp">Sign out</a></dd>
              </dl>
            </li>
            <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
              <a href="javascript:;">
                <i class="layui-icon layui-icon-more-vertical"></i>
              </a>
            </li>
          </ul>
        </div>
        
        <div class="layui-side layui-bg-black">
          <div class="layui-side-scroll">
            <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
            <ul id="menu" class="layui-nav layui-nav-tree" lay-filter="menu">
         <li class="layui-nav-item layui-nav-itemed">
                <a class="" href="javascript:;">menu group 1</a>
                <dl class="layui-nav-child">
                  <dd><a href="javascript:;">menu 1</a></dd>
                  <dd><a href="javascript:;">menu 2</a></dd>
                  <dd><a href="javascript:;">menu 3</a></dd>
                  <dd><a href="">the links</a></dd>
                </dl>
              </li>
              <li class="layui-nav-item">
                <a href="javascript:;">menu group 2</a>
                <dl class="layui-nav-child">
                  <dd><a href="javascript:;">list 1</a></dd>
                  <dd><a href="javascript:;">list 2</a></dd>
                  <dd><a href="">超链接</a></dd>
                </dl>
              </li>
              <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
              <li class="layui-nav-item"><a href="">the links</a></li>
            </ul>
          </div>
        </div>
        
        <div class="layui-body">
          <!-- 内容主体区域 -->
          <div style="padding: 15px;">内容主体区域。记得修改 layui.css 和 js 的路径</div>
        </div>
        
        <div class="layui-footer">
          <!-- 底部固定区域 -->
                  底部固定区域
        </div>
      </div>
      
      
      <script>
      //JS 
      /* 头部 */
      /* layui.use(['element', 'layer', 'util'], function(){
        var element = layui.element
        ,layer = layui.layer
        ,util = layui.util
        ,$ = layui.$;
        
        //头部事件
        util.event('lay-header-event', {
          //左侧菜单事件
          menuLeft: function(othis){
            layer.msg('展开左侧菜单的操作', {icon: 0});
          }
          ,menuRight: function(){
            layer.open({
              type: 1
              ,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
              ,area: ['260px', '100%']
              ,offset: 'rt' //右上角
              ,anim: 5
              ,shadeClose: true
            });
          }
        });
        
      }); */
      
      /* 树形菜单 */
      layui.use(['element', 'layer', 'util'], function(){
      	  var element = layui.element
      	  ,layer = layui.layer
      	  ,util = layui.util
      	  ,$ = layui.$;
      	  
      	 $.ajax({
      		 url:"${pageContext.request.contextPath}/permission.action?methodName=menus",
       		dataType:'json',
       		method: 'post',
      		success: function(data) {
      			console.info(data)
      			var content=' ';
      			$.each(data,function(i,n){
      				content+=' <li class="layui-nav-item layui-nav-itemed"> ';
      				content+='		<a class="" href="javascript:;">'+n.text+'</a> ';  
      				
      				if(n.hasChildren){
      				var children =n.children;
      				content+='<dl class="layui-nav-child"> ';
      				$.each(children,function(idx,nodes){
      					content+=' <dd><a href="javascript:;">'+nodes.text+'</a></dd> ';
      				})
      				content+='</dl>';
      				}
      				
      				content+=' </li>';
      			
      			})
      			
      			$("#menu").html(content);
      			 element.render();		
      		}
      	 })
      });
      	  
      
      
      
      
      </script>
      <script type="text/javascript">
      
      </script>
      </body>
      </html>
  • 7.最终效果展示

四.详细案例解析

实现效果

 

思路

  1. 先要从layui的文档中找到树形菜单的样式,将其粘贴过来使用
  2. 观察树形菜单➡所需数据【json&&有层级关系的数据】
  3. 将原本的数据查询出来,借助工具类将其转换成我们所需要的数据
  4. 将所需要的数据进行循环遍历
    1. 外层循环:一级菜单
    2. 内层循环:二级菜单(需要与一级菜单的id相比,一样便遍历)

表结构

实体类

package com.wh.entity;

public class Module {
private int id;
private int pid;
private String name;
private String icon;
private String url;
private int sort;

public Module() {
	// TODO Auto-generated constructor stub
}

public Module(int id, int pid, String name, String icon, String url, int sort) {
	super();
	this.id = id;
	this.pid = pid;
	this.name = name;
	this.icon = icon;
	this.url = url;
	this.sort = sort;
}

public int getId() {
	return id;
}

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

public int getPid() {
	return pid;
}

public void setPid(int pid) {
	this.pid = pid;
}

public String getName() {
	return name;
}

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

public String getIcon() {
	return icon;
}

public void setIcon(String icon) {
	this.icon = icon;
}

public String getUrl() {
	return url;
}

public void setUrl(String url) {
	this.url = url;
}

public int getSort() {
	return sort;
}

public void setSort(int sort) {
	this.sort = sort;
}

@Override
public String toString() {
	return "Module [id=" + id + ", pid=" + pid + ", name=" + name + ", icon=" + icon + ", url=" + url + ", sort=" + sort
			+ "]";
}




}

工具类

package com.zking.util;
 
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
 
/**
 * 提供了一组获得或关闭数据库对象的方法
 * 
 */
public class DBAccess {
	private static String driver;
	private static String url;
	private static String user;
	private static String password;
 
	static {// 静态块执行一次,加载 驱动一次
		try {
			InputStream is = DBAccess.class
					.getResourceAsStream("config.properties");
 
			Properties properties = new Properties();
			properties.load(is);
 
			driver = properties.getProperty("driver");
			url = properties.getProperty("url");
			user = properties.getProperty("user");
			password = properties.getProperty("pwd");
 
			Class.forName(driver);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
 
	/**
	 * 获得数据连接对象
	 * 
	 * @return
	 */
	public static Connection getConnection() {
		try {
			Connection conn = DriverManager.getConnection(url, user, password);
			return conn;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
 
	public static void close(ResultSet rs) {
		if (null != rs) {
			try {
				rs.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
 
	public static void close(Statement stmt) {
		if (null != stmt) {
			try {
				stmt.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
 
	public static void close(Connection conn) {
		if (null != conn) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
				throw new RuntimeException(e);
			}
		}
	}
 
	public static void close(Connection conn, Statement stmt, ResultSet rs) {
		close(rs);
		close(stmt);
		close(conn);
	}
 
	public static boolean isOracle() {
		return "oracle.jdbc.driver.OracleDriver".equals(driver);
	}
 
	public static boolean isSQLServer() {
		return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
	}
	
	public static boolean isMysql() {
		return "com.mysql.cj.jdbc.Driver".equals(driver);
	}
 
	public static void main(String[] args) {
		Connection conn = DBAccess.getConnection();
		System.out.println(conn);
		DBAccess.close(conn);
		System.out.println("isOracle:" + isOracle());
		System.out.println("isSQLServer:" + isSQLServer());
		System.out.println("isMysql:" + isMysql());
		System.out.println("数据库连接(关闭)成功");
	}
}
package com.zking.util;
 
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/*
 * 通用的增删改以及查询
 */
public class BaseDao<T> {
	/**
	 * @author W
	 * 
	 * 通用版分页查询
	 * @param sql sql语句
	 * @param clas 指定对象类类
	 * @param pageBean 分页工具类
	 * @return list 结果集
	 * @throws Exception
	 */
	public List<T> executeQuery (String sql,Class clas,PageBean pageBean) throws Exception{
		Connection conn = null;//连接对象
		PreparedStatement ps = null;//执行对象
		ResultSet rs = null;//结果集对象
		List<T> list= new ArrayList<T>();//集合
		/**
		 * 是否分页?
		 */
		if(pageBean!=null&&pageBean.isPagination()) {//如果分页的工具类传进来了【不为空】,并且分页工具类的是否分页的方法的返回值是true时
			//那么便定义分页的sql语句和符合条件的总记录数
			String countSql=getCountSql(sql);//符合条件的总记录数的sql
			conn = DBAccess.getConnection();//获取连接对象
			ps = conn.prepareStatement(countSql);//执行sql语句
			rs=ps.executeQuery();//获取结果集对象
			if(rs.next()) {
				pageBean.setTotal(rs.getObject("n").toString());//结果集查询的结果设置到分页工具类的总记录的方法中
			}
			String pageSql=getPageSql(sql,pageBean);//分页的sql
			conn = DBAccess.getConnection();//获取连接对象
			ps = conn.prepareStatement(pageSql);//执行sql语句
			rs=ps.executeQuery();//获取结果集对象
		}else {
			conn = DBAccess.getConnection();//获取连接对象
			ps = conn.prepareStatement(sql);//执行sql语句
			rs=ps.executeQuery();//获取结果集对象
		}
		while(rs.next()) {
			T t= (T) clas.newInstance();//类类
			Field[] fields = clas.getDeclaredFields();//拿到特定实体的所有的属性
			for (Field field : fields) {//遍历所有的属性
				field.setAccessible(true);//打开权限通道,可以拿到私有的属性
				field.set(t, rs.getObject(field.getName()));//为指定的实体对象更改指定的属性
			}
			list.add(t);//将其加入到集合中
		}
		return list;//返回集合
	}
 
	/**
	 * 符合条件的总记录数
	 * @param sql 查询的sql语句
	 * @return 符合条件的总记录数的sql语句
	 */
	private String getCountSql(String sql) {
		return " select count(1) as n from ( "+sql+" ) t";//sql语句
	}
 
	/**
	 * 分页的sql语句
	 * @param sql 查询的sql语句
	 * @param pageBean 分页工具类
	 * @return 分页的sql语句
	 */
	private String getPageSql(String sql, PageBean pageBean) {
		return sql+" limit  "+pageBean.getStartIndex()+", "+pageBean.getRows();//sql语句
	}
	
	
	
	
	/**
	 * @author W
	 * 通用的增删改
	 */
	public int executeUpdate (T t,String sql,String [] attr) throws Exception{
		Connection conn = DBAccess.getConnection();//获取连接对象
		PreparedStatement ps =conn.prepareStatement(sql);//执行sql语句
		for (int i = 0; i < attr.length; i++) {//遍历装有对象属性的数组
			Field field = t.getClass().getDeclaredField(attr[i]);//动态实例化并拿到此对象中所有属性
			field.setAccessible(true);//打开获取私有属性的通道
			ps.setObject(i+1, field.get(t));//为占位符赋值
		}
		return ps.executeUpdate();
	}
 
}
package com.zking.util;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/*
*将源数据转换成有层级关系的数据
*/
public class TreeVo<T> {
	/**
	 * 节点ID
	 */
	private String id;
	/**
	 * 显示节点文本
	 */
	private String text;
	/**
	 * 节点状态,open closed
	 */
	private Map<String, Object> state;
	/**
	 * 节点是否被选中 true false
	 */
	private boolean checked = false;
	/**
	 * 节点属性
	 */
	private Map<String, Object> attributes;

	/**
	 * 节点的子节点
	 */
	private List<TreeVo<T>> children = new ArrayList<TreeVo<T>>();

	/**
	 * 父ID
	 */
	private String parentId;
	/**
	 * 是否有父节点
	 */
	private boolean hasParent = false;
	/**
	 * 是否有子节点
	 */
	private boolean hasChildren = false;

	public String getId() {
		return id;
	}

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

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}

	public Map<String, Object> getState() {
		return state;
	}

	public void setState(Map<String, Object> state) {
		this.state = state;
	}

	public boolean isChecked() {
		return checked;
	}

	public void setChecked(boolean checked) {
		this.checked = checked;
	}

	public Map<String, Object> getAttributes() {
		return attributes;
	}

	public void setAttributes(Map<String, Object> attributes) {
		this.attributes = attributes;
	}

	public List<TreeVo<T>> getChildren() {
		return children;
	}

	public void setChildren(List<TreeVo<T>> children) {
		this.children = children;
	}

	public boolean isHasParent() {
		return hasParent;
	}

	public void setHasParent(boolean isParent) {
		this.hasParent = isParent;
	}

	public boolean isHasChildren() {
		return hasChildren;
	}

	public void setChildren(boolean isChildren) {
		this.hasChildren = isChildren;
	}

	public String getParentId() {
		return parentId;
	}

	public void setParentId(String parentId) {
		this.parentId = parentId;
	}

	public TreeVo(String id, String text, Map<String, Object> state, boolean checked, Map<String, Object> attributes,
                  List<TreeVo<T>> children, boolean isParent, boolean isChildren, String parentID) {
		super();
		this.id = id;
		this.text = text;
		this.state = state;
		this.checked = checked;
		this.attributes = attributes;
		this.children = children;
		this.hasParent = isParent;
		this.hasChildren = isChildren;
		this.parentId = parentID;
	}

	public TreeVo() {
		super();
	}

}
package com.zking.util;
 
import java.io.PrintWriter;
 
import javax.servlet.http.HttpServletResponse;
 
import com.fasterxml.jackson.databind.ObjectMapper;
/*
*jaso格式数据的转换与回显
*/
 
public class ResponseUtil {
 
	public static void write(HttpServletResponse response,Object o)throws Exception{
		response.setContentType("text/html;charset=utf-8");
		PrintWriter out=response.getWriter();
		out.println(o.toString());
		out.flush();
		out.close();
	}
	
	public static void writeJson(HttpServletResponse response,Object o)throws Exception{
		ObjectMapper om = new ObjectMapper();
//		om.writeValueAsString(o)代表了json串
		write(response, om.writeValueAsString(o));
	}
}

配置文件

#oracle9i
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:ora9
#user=test
#pwd=test
 
 
#sql2005
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#url=jdbc:sqlserver://localhost:1423;DatabaseName=test
#user=sa
#pwd=sa
 
 
#sql2000
#driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB
#user=sa
#pwd=888888
 
#mysql5
#driver=com.mysql.jdbc.Driver
#url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
#user=mybatis_ssm
#pwd=xiaoli
 
#mysql8
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis_ssm?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&useSSL=true
user=root
pwd=123456
 
 
 
<?xml version="1.0" encoding="UTF-8"?>
<config>
	
	<action path="/user" type="com.wh.web.UserAction">
	</action>
	
	
	<action path="/permission" type="com.wh.web.PermissionAction">
	</action>

	<action path="/module" type="com.wh.web.ModuleAction">
	</action>
</config>
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
 <display-name>T269_mvc_crud</display-name>
  <servlet>
  	<servlet-name>mvc</servlet-name>
  	<servlet-class>com.zking.framework.DispatchServlet</servlet-class>
  	<init-param>
  		<param-name>configurationLocation</param-name>
  		<param-value>/mvc.xml</param-value>
  	</init-param>
  </servlet>
  <servlet-mapping>
  	<servlet-name>mvc</servlet-name>
  	<url-pattern>*.action</url-pattern>
  </servlet-mapping>
</web-app>

公共页面(引入的文件)

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<meta name="viewport" content="width=device-width,initial-scale=1.33,minimum-scale=1.0,maximum-scale=1.0">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="renderer" content="webkit">
<meta http-equiv="Content-Language" content="zh-CN">
<link rel="stylesheet" rev="stylesheet" href="${pageContext.request.contextPath}/static/layui/css/layui.css" type="text/css" media="all">
<script type="text/javascript" src="${pageContext.request.contextPath}/static/layui/layui.js"></script>
 

jsp界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE>
<html>
<head>
  <%@include file="/common/head.jsp" %>
</head>
<body>
<div class="layui-layout layui-layout-admin">
  <div class="layui-header">
    <div class="layui-logo layui-hide-xs layui-bg-black">layout demo</div>
    <!-- 头部区域(可配合layui 已有的水平导航) -->
    <ul class="layui-nav layui-layout-left">
      <!-- 移动端显示 -->
      <li class="layui-nav-item layui-show-xs-inline-block layui-hide-sm" lay-header-event="menuLeft">
        <i class="layui-icon layui-icon-spread-left"></i>
      </li>
      <!-- Top导航栏 -->
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 1</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 2</a></li>
      <li class="layui-nav-item layui-hide-xs"><a href="">nav 3</a></li>
      <li class="layui-nav-item">
        <a href="javascript:;">nav groups</a>
        <dl class="layui-nav-child">
          <dd><a href="">menu 11</a></dd>
          <dd><a href="">menu 22</a></dd>
          <dd><a href="">menu 33</a></dd>
        </dl>
      </li>
    </ul>
    <!-- 个人头像及账号操作 -->
    <ul class="layui-nav layui-layout-right">
      <li class="layui-nav-item layui-hide layui-show-md-inline-block">
        <a href="javascript:;">
          <img src="//tva1.sinaimg.cn/crop.0.0.118.118.180/5db11ff4gw1e77d3nqrv8j203b03cweg.jpg" class="layui-nav-img">
          tester
        </a>
        <dl class="layui-nav-child">
          <dd><a href="">Your Profile</a></dd>
          <dd><a href="">Settings</a></dd>
          <dd><a href="login.jsp">Sign out</a></dd>
        </dl>
      </li>
      <li class="layui-nav-item" lay-header-event="menuRight" lay-unselect>
        <a href="javascript:;">
          <i class="layui-icon layui-icon-more-vertical"></i>
        </a>
      </li>
    </ul>
  </div>
  
  <div class="layui-side layui-bg-black">
    <div class="layui-side-scroll">
      <!-- 左侧导航区域(可配合layui已有的垂直导航) -->
      <ul id="menu" class="layui-nav layui-nav-tree" lay-filter="menu">
   <li class="layui-nav-item layui-nav-itemed">
          <a class="" href="javascript:;">menu group 1</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">menu 1</a></dd>
            <dd><a href="javascript:;">menu 2</a></dd>
            <dd><a href="javascript:;">menu 3</a></dd>
            <dd><a href="">the links</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item">
          <a href="javascript:;">menu group 2</a>
          <dl class="layui-nav-child">
            <dd><a href="javascript:;">list 1</a></dd>
            <dd><a href="javascript:;">list 2</a></dd>
            <dd><a href="">超链接</a></dd>
          </dl>
        </li>
        <li class="layui-nav-item"><a href="javascript:;">click menu item</a></li>
        <li class="layui-nav-item"><a href="">the links</a></li>
      </ul>
    </div>
  </div>
  
  <div class="layui-body">
    <!-- 内容主体区域 -->
      <div style="padding: 15px;">树形结构的演示-是辉辉啦!!</div>
  </div>
  
  <div class="layui-footer">
    <!-- 底部固定区域 -->
            底部固定区域
  </div>
</div>


<script>
//JS 
/* 头部 */
/* layui.use(['element', 'layer', 'util'], function(){
  var element = layui.element
  ,layer = layui.layer
  ,util = layui.util
  ,$ = layui.$;
  
  //头部事件
  util.event('lay-header-event', {
    //左侧菜单事件
    menuLeft: function(othis){
      layer.msg('展开左侧菜单的操作', {icon: 0});
    }
    ,menuRight: function(){
      layer.open({
        type: 1
        ,content: '<div style="padding: 15px;">处理右侧面板的操作</div>'
        ,area: ['260px', '100%']
        ,offset: 'rt' //右上角
        ,anim: 5
        ,shadeClose: true
      });
    }
  });
  
}); */

/* 树形菜单 */
layui.use(['element', 'layer', 'util'], function(){
	  var element = layui.element
	  ,layer = layui.layer
	  ,util = layui.util
	  ,$ = layui.$;
	  
	 $.ajax({
		 url:"${pageContext.request.contextPath}/module.action?methodName=menus",
 		dataType:'json',
 		method: 'post',
		success: function(data) {
			console.info(data)
			var content=' ';
			$.each(data,function(i,n){
				content+=' <li class="layui-nav-item layui-nav-itemed"> ';
				content+='		<a class="" href="javascript:;">'+n.text+'</a> ';  
				
				
				if(n.hasChildren){
				var children =n.children;
				content+='<dl class="layui-nav-child"> ';
				$.each(children,function(idx,nodes){
					content+=' <dd><a href="javascript:;">'+nodes.text+'</a></dd> ';
				})
				content+='</dl>';
				}
				
				content+=' </li>';
			
			})
			
			$("#menu").html(content);
			 element.render(); 		
		}
	 })
});
	  




</script>
<script type="text/javascript">

</script>
</body>
</html>

dao

package com.wh.dao;

import java.util.ArrayList;
import java.util.List;

import com.wh.entity.Module;
import com.wh.entity.Permission;
import com.wh.entity.User;
import com.zking.util.BaseDao;
import com.zking.util.BuildTree;
import com.zking.util.PageBean;
import com.zking.util.TreeVo;

public class ModuleDao extends BaseDao<Module>{
	//查询所有
		public List< Module> list(  Module  module, PageBean pageBean) throws Exception {
	  String sql="select * from t_module";
			return super.executeQuery(sql,  Module.class, pageBean);
		}
	
	
	//将原数据转换成有层级关系的数据(借助自定义 工具类TreeVo完成)
	public List<TreeVo< Module>> menus(  Module  module, PageBean pageBean) throws Exception {
		List<TreeVo<Module>> menus = new ArrayList<>();
		List<Module> list = this.list(module, pageBean);
		for (Module m : list) {
			TreeVo<Module> tv = new TreeVo<>();
			tv.setId(m.getId()+"");
			tv.setParentId(m.getPid()+"");
			tv.setText(m.getName());
			menus.add(tv);
		}
//		return menus;
		return BuildTree.buildList(menus, "-1");//-1是顶级节点的id
	}
		
		
}

servlet

package com.wh.web;

import java.util.List;

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

import com.wh.dao.ModuleDao;
import com.wh.dao.PermissionDao;
import com.wh.entity.Module;
import com.wh.entity.Permission;
import com.zking.framework.ActionSupport;
import com.zking.framework.ModelDriver;
import com.zking.util.PageBean;
import com.zking.util.ResponseUtil;
import com.zking.util.TreeVo;

public class ModuleAction extends ActionSupport implements ModelDriver< Module>{
private  Module  module = new  Module();
private  ModuleDao md = new  ModuleDao();

	public void menus(HttpServletRequest req, HttpServletResponse resp) {
				try {
					List<TreeVo< Module>> menus = md.menus(null, null);
					ResponseUtil.writeJson(resp, menus);
				} catch (Exception e) {
					e.printStackTrace();
				}
	}
	@Override
	public  Module getModel() {
		return  module;
	}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/744193.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

表格编程之争:Python VS VBA?Excel用户:新编程语言才真香

Python和VBA哪个更好用&#xff1f; Python和VBA是两种不同的编程语言&#xff0c;它们都有自己的特点和优缺点。在表格编程方面&#xff0c;VBA在Excel中的应用非常广泛&#xff0c;可以通过宏来实现自动化操作和数据处理&#xff0c;也可以通过VBA代码来实现自定义函数和界面…

python qt安装软件包

安装 opencv pip install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple/ 安装pyqt5 pip install pyqt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ 安装pyqt5-tools pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/

RLHF-基于人类反馈的强化学习

RLHF 文章目录 RLHF强化学习基础回顾为什么要使用基于人类反馈的强化学习大纲RLHF的起源大预言模型中的RLHF案例 ChatGPT RLHF中的技术细节预训练语言模型训练奖励模型基于RL进行微调 RLHF 的未来 强化学习基础回顾 智能体通过采取行动与环境进行交互&#xff0c;并返回状态和奖…

【C语言督学营 第十八天】考研408排序大题初探(将排序思想融入题目)

文章目录 题目一分析代码实战 题目二分析代码实战 补充(快排与归并)数据结构大题注意点&#xff01;&#xff01;&#xff01;(评分标准) 题目一 分析 (1&#xff09;算法的基本设计思想 由题意知&#xff0c;将最小的nl2个元素放在Ai中&#xff0c;其余的元素放在A2中&#x…

FreeRTOS实时操作系统(十三)任务通知

系列文章目录 文章目录 系列文章目录任务通知任务通知值和通知状态任务通知值通知状态 任务通知API函数发送通知函数接收通知函数 实验测试模拟二值信号量实验模拟计数型信号量模拟事件标志组实验模拟消息邮箱实验 任务通知 任务通知&#xff1a;用来通知任务的&#xff0c;任…

ATMEGA16 Proteus仿真自动人体感应电风扇DS18B20温度 -0069

ATMEGA16 Proteus仿真自动人体感应电风扇DS18B20温度 -0069 Proteus仿真小实验&#xff1a; ATMEGA16 Proteus仿真自动人体感应电风扇DS18B20温度 -0069 功能&#xff1a; Protues版本&#xff1a;7.8 程序编写&#xff1a;ICCAVR:7.12 硬件组成&#xff1a;ATMEGA16单片机…

嵌入式开发之编码器速度采集

光电编码器&#xff0c;是一种通过光电转换将输出轴上的机械几何位移量转换成脉冲或数字量的传感器。这是应用最多的传感器&#xff0c;光电编码器是由光源、光码盘和光敏元件组成。光栅盘是在一定直径的圆板上等分地开通若干个长方形孔。由于光电码盘与电动机同轴&#xff0c;…

spark和zeppelin认证不一致:Only one of --proxy-user or --principal can be provided

spark和zeppelin认证不一致&#xff1a;Only one of --proxy-user or --principal can be provided 如果配置principal认证方式&#xff0c;zeppelin走的是hadoop权限&#xff0c;如果配置proxy-user认证方式&#xff0c;zeppelin走的是当前登录用户的权限&#xff08;ranger控…

GitHub上cambel的ur3项目调试经验

按照https://github.com/cambel/ur3/wiki/Compile-from-source配置环境时&#xff0c;遇到以下问题&#xff1a; catkin clean时报错 [clean] Error: The current or desired workspace could not be determined. Please run catkin clean from within a catkin workspace or…

【学会动态规划】第 N 个泰波那契数(1)

目录 动态规划怎么学&#xff1f; 1. 题目解析 2. 算法原理 1. 状态表示 2. 状态转移方程 3. 初始化 4. 填表顺序 5. 返回值 3. 代码编写 4. 空间优化 写在最后 动态规划怎么学&#xff1f; 学习一个算法没有捷径&#xff0c;更何况是学习动态规划&#xff0c; 跟…

MySQL 中索引是如何实现的,有哪些类型的索引,如何进行优化索引

MySQL 中的索引 前言 上篇文章聊完了 MySQL 中的锁&#xff0c;这里接着来看下 MySQL 中的索引。 一般当我们数据库中的某些查询比较慢的时候&#xff0c;正常情况下&#xff0c;一顿分析下来&#xff0c;大多数我们会考虑对这个查询加个索引&#xff0c;那么索引是如何工作的呢…

从零开始的前后端分离项目学习(前后端从零环境搭建)

一、 前后端分离介绍&#xff1a; 前端独立编写客户端代码&#xff08;用户交互数据展示&#xff09;&#xff0c;后端独立编写服务端代码&#xff08;提供数据处理接口&#xff09;&#xff0c;并提供数据接口就行。 前端通过Ajax访问后端数据借口&#xff0c;将model展示到…

使用VESD脉冲离子风机5年内至少可节省一半的维护成本

之前的文章有给大家详细介绍过&#xff0c;来自VESD的脉冲离子风机&#xff0c;它有着特殊的设计&#xff1a;插拔式结构和可水洗针架&#xff0c;因此对我们的很多客户来说&#xff0c;这款风机性价比是非常高的。 早在15年以前&#xff0c;VESD就对市面上大部分风机进行过测试…

解决Google浏览器网页覆盖问题

在使用 Google 进行搜索的时候出现打开新页面会覆盖当前页面的问题 针对此问题&#xff0c;解决方法如下&#xff1a; 1、首先在浏览器的地址栏中随便搜索内容 2、页面的 右上角有个⚙️的设置图标&#xff0c;点进去 点击 “查看所有设置” 3、在结果打开方式中进行勾选 设…

uniapp打包APP实现应用内整包更新或热更新

思路&#xff1a; 1.首先要理解更新方式的区别 静默更新、弱更新以及强制更新。 APP更新机制-静默更新、弱更新、强更新 - 知乎 2.其次要理解不同更新方式要用到的插件----------这里推荐插件应用市场的插件。 app升级、整包更新和热更新组件 支持vue3 支持打开安卓、苹果应…

使用 SMT求解机 根据变迁关系生成迁移后系统的状态

本文的例子来源于2011年发布的论文 IC3: Where Monolithic and Incremental Meet 文章目录 Ⅰ、变迁系统的介绍状态图变迁公式 Ⅱ、SMT求解机简介公式的计算计算另一状态 结果展示参考文献 Ⅰ、变迁系统的介绍 状态图 论文中给出了一个系统的状态迁移图和它的的变迁公式。现在…

【近场社交项目】数据库系统期末设计——概念设计部分

数据库系统期末设计——概念设计部分&#x1f60e; 前言&#x1f64c;项目设计&#xff08;1&#xff09;各个实体属性ER图&#xff08;2&#xff09;各个业务功能的ER图 总结撒花&#x1f49e; &#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的座右铭&#x…

【Redis】特殊数据类型 Geo (地理位置)

&#x1f3af;前言 除了五中基本的数据类型外&#xff0c;Redis还支持两种特殊的数据类型&#xff0c;第一种 Geo (地理位置)&#xff1a;用于存储地理位置相关的数据&#xff0c;例如经纬度、距离等。第二种 Stream (流)&#xff1a;是一个高级的列表类型&#xff0c;支持对列…

Python基于pandas库导出excel文件

将Pandas数据框架导出到Excel文件中 让我们看看如何将Pandas数据框架导出到Excel文件中。 实列代码&#xff1a; import time import pandas as pd from io import BytesIO from flask import make_response,def export_navi():# 所有DataFrame合并集合df_list []# 创建一个数…

理工大学|校企联手创典范,布局存储新未来

某理工大学地质灾害防治与地质环境保护国家重点实验室的前身是1989年由原国家计委、国家教委批准&#xff0c;在某理工大学&#xff08;原某地质学院&#xff09;“地质工程”国家重点学科基础上建立的国家专业实验室&#xff0c;该实验室是我国地质灾害防治领域目前唯一的国家…