当前位置: 首页 > news >正文

重庆做网站开发的公司有哪些网站流量统计

重庆做网站开发的公司有哪些,网站流量统计,3d人物建模软件,网站上的3d产品展示怎么做Java实现树结构(为前端实现级联菜单或者是下拉菜单接口) 我们常常会遇到这样一个问题,就是前端要实现的样式是一个级联菜单或者是下拉树,如图 这样的数据接口是怎么实现的呢,是什么样子的呢? 我们可以看看 …

Java实现树结构(为前端实现级联菜单或者是下拉菜单接口)

在这里插入图片描述

我们常常会遇到这样一个问题,就是前端要实现的样式是一个级联菜单或者是下拉树,如图

在这里插入图片描述
在这里插入图片描述
这样的数据接口是怎么实现的呢,是什么样子的呢?
我们可以看看 Elemui中的假数据

<el-cascader :options="options" clearable></el-cascader><script>export default {data() {return {options: [{value: 'zhinan',label: '指南',children: [{value: 'shejiyuanze',label: '设计原则',children: [{value: 'yizhi',label: '一致'}, {value: 'fankui',label: '反馈'}, {value: 'xiaolv',label: '效率'}, {value: 'kekong',label: '可控'}]}, {value: 'daohang',label: '导航',children: [{value: 'cexiangdaohang',label: '侧向导航'}, {value: 'dingbudaohang',label: '顶部导航'}]}]}, {value: 'zujian',label: '组件',children: [{value: 'basic',label: 'Basic',children: [{value: 'layout',label: 'Layout 布局'}, {value: 'color',label: 'Color 色彩'}, {value: 'typography',label: 'Typography 字体'}, {value: 'icon',label: 'Icon 图标'}, {value: 'button',label: 'Button 按钮'}]}, {value: 'form',label: 'Form',children: [{value: 'radio',label: 'Radio 单选框'}, {value: 'checkbox',label: 'Checkbox 多选框'}, {value: 'input',label: 'Input 输入框'}, {value: 'input-number',label: 'InputNumber 计数器'}, {value: 'select',label: 'Select 选择器'}, {value: 'cascader',label: 'Cascader 级联选择器'}, {value: 'switch',label: 'Switch 开关'}, {value: 'slider',label: 'Slider 滑块'}, {value: 'time-picker',label: 'TimePicker 时间选择器'}, {value: 'date-picker',label: 'DatePicker 日期选择器'}, {value: 'datetime-picker',label: 'DateTimePicker 日期时间选择器'}, {value: 'upload',label: 'Upload 上传'}, {value: 'rate',label: 'Rate 评分'}, {value: 'form',label: 'Form 表单'}]}, {value: 'data',label: 'Data',children: [{value: 'table',label: 'Table 表格'}, {value: 'tag',label: 'Tag 标签'}, {value: 'progress',label: 'Progress 进度条'}, {value: 'tree',label: 'Tree 树形控件'}, {value: 'pagination',label: 'Pagination 分页'}, {value: 'badge',label: 'Badge 标记'}]}, {value: 'notice',label: 'Notice',children: [{value: 'alert',label: 'Alert 警告'}, {value: 'loading',label: 'Loading 加载'}, {value: 'message',label: 'Message 消息提示'}, {value: 'message-box',label: 'MessageBox 弹框'}, {value: 'notification',label: 'Notification 通知'}]}, {value: 'navigation',label: 'Navigation',children: [{value: 'menu',label: 'NavMenu 导航菜单'}, {value: 'tabs',label: 'Tabs 标签页'}, {value: 'breadcrumb',label: 'Breadcrumb 面包屑'}, {value: 'dropdown',label: 'Dropdown 下拉菜单'}, {value: 'steps',label: 'Steps 步骤条'}]}, {value: 'others',label: 'Others',children: [{value: 'dialog',label: 'Dialog 对话框'}, {value: 'tooltip',label: 'Tooltip 文字提示'}, {value: 'popover',label: 'Popover 弹出框'}, {value: 'card',label: 'Card 卡片'}, {value: 'carousel',label: 'Carousel 走马灯'}, {value: 'collapse',label: 'Collapse 折叠面板'}]}]}, {value: 'ziyuan',label: '资源',children: [{value: 'axure',label: 'Axure Components'}, {value: 'sketch',label: 'Sketch Templates'}, {value: 'jiaohu',label: '组件交互文档'}]}]}}}
</script>

可以看见,这样的数据我们直接用SQL查出来是会损耗SQL性能的,我们这里展示如何在业务层做数据处理,实现树结构,这里就以若依的菜单数据为例,做一个基本演示!
查询数据我们分为两种,一种是获取指定的菜单,一种是获取全部的,获取指定的菜单我们需要写一个递归SQL,比如

在这里插入图片描述
我们如果获取全部那就是正常的查询所以,但是只要目录管理下面的菜单结构,不要其他的,那么这个SQL就是这样的:
如果想从sys_menu表中查询并获取菜单树的数据,可以使用递归查询。以下是一个基于MySQL的示例查询,该查询假设每个记录都有唯一的menu_id标识符和parent_id表示父菜单ID:

WITH RECURSIVE MenuCTE AS (SELECT menu_id,menu_name,parent_id,order_num,path,component,query,is_frame,is_cache,menu_type,visible,status,perms,icon,create_by,create_time,update_by,update_time,remarkFROM sys_menuWHERE parent_id = 0  -- 根节点的条件UNION ALLSELECT m.menu_id,m.menu_name,m.parent_id,m.order_num,m.path,m.component,m.query,m.is_frame,m.is_cache,m.menu_type,m.visible,m.status,m.perms,m.icon,m.create_by,m.create_time,m.update_by,m.update_time,m.remarkFROM sys_menu mJOIN MenuCTE cte ON m.parent_id = cte.menu_id
)
SELECT * FROM MenuCTE;

这个查询使用了MySQL的递归CTE(Common Table Expressions)功能,通过WITH RECURSIVE来逐级查询父菜单与子菜单的关系。查询结果包含了所有菜单及其层次结构关系。
我们分析一下这个SQL
这是一个使用递归CTE(Common Table Expressions)的SQL查询,用于获取具有层次结构关系的菜单数据。以下是对查询各部分的解释:

  1. WITH RECURSIVE MenuCTE AS: 这是一个递归CTE的开始,MenuCTE 是一个临时表名。递归CTE用于递归地查询表中的数据。

  2. SELECT ... FROM sys_menu WHERE parent_id = 0: 这是递归CTE的初始查询部分,它选择根节点(parent_id = 0)的菜单记录。

  3. UNION ALL: 这是联结两个查询结果集的关键字,它将上述初始查询结果与后续递归查询的结果联结在一起。

  4. SELECT ... FROM sys_menu m JOIN MenuCTE cte ON m.parent_id = cte.menu_id: 这是递归查询的部分,通过连接sys_menu表自身,并使用递归关系 m.parent_id = cte.menu_id 来获取每个菜单的子菜单。

  5. 最后,整个递归CTE的最后部分是 SELECT * FROM MenuCTE,它选择了所有递归CTE的结果,包括根节点和其下的所有子节点。

该查询的结果是包含所有菜单数据的表,每一行都表示一个菜单项,具有其父菜单的引用关系,形成了一个层次结构。这对于表示树形结构的数据非常有用,例如用于构建具有层次关系的菜单系统。
当然,毫无疑问,获取出来的数据就是普通列表,下面我们就进行处理:

    public static List<SysMenu> buildMenuTree(List<SysMenu> menuList) {Map<Long, SysMenu> menuMap = new HashMap<>();// 创建一个菜单ID到菜单对象的映射for (SysMenu menu : menuList) {menuMap.put(menu.getMenuId(), menu);}// 构建菜单树List<SysMenu> menuTree = new ArrayList<>();for (SysMenu menu : menuList) {Long parentId = menu.getParentId();if (parentId != null && menuMap.containsKey(parentId)) {SysMenu parentMenu = menuMap.get(parentId);parentMenu.getChildren().add(menu);} else {menuTree.add(menu); // 没有父菜单或父菜单未找到,将其作为根节点添加到树中}}return menuTree;}

这段 Java 代码是一个用于构建菜单树的方法,它接受一个包含 SysMenu 对象的列表作为输入,然后返回一个构建好的菜单树的列表。

让我对这段代码进行详细解读:

  1. 创建映射表:

    Map<Long, SysMenu> menuMap = new HashMap<>();
    

    在这里,创建了一个 HashMap 对象 menuMap,用于将菜单ID映射到相应的 SysMenu 对象。

  2. 建立映射关系:

    for (SysMenu menu : menuList) {menuMap.put(menu.getMenuId(), menu);
    }
    

    通过遍历输入的菜单列表 menuList,将每个菜单的 menuId 与对应的 SysMenu 对象建立映射关系。

  3. 构建菜单树:

    List<SysMenu> menuTree = new ArrayList<>();
    for (SysMenu menu : menuList) {Long parentId = menu.getParentId();if (parentId != null && menuMap.containsKey(parentId)) {SysMenu parentMenu = menuMap.get(parentId);parentMenu.getChildren().add(menu);} else {menuTree.add(menu); // 没有父菜单或父菜单未找到,将其作为根节点添加到树中}
    }
    

    遍历菜单列表 menuList,对于每个菜单,检查其 parentId 是否存在并且在 menuMap 中有对应的父菜单。如果是,将当前菜单添加到其父菜单的子菜单列表 children 中;如果不是,说明当前菜单是根节点,将其添加到 menuTree 中。

  4. 返回菜单树:

    return menuTree;
    

    返回构建好的菜单树列表 menuTree

这样,该方法将输入的扁平的菜单列表转换为一个带有层次结构的菜单树,其中每个菜单节点都包含了其子菜单的引用。这种结构更适合在用户界面上展示树形菜单。
这是我们自己写的,然后看看人家若依自己的,用到了递归:

    /*** 构建前端所需要树结构** @param menus 菜单列表* @return 树结构列表*/public List<SysMenu> buildMenuTree(List<SysMenu> menus) {List<SysMenu> returnList = new ArrayList<SysMenu>();List<Long> tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext(); ) {SysMenu menu = (SysMenu) iterator.next();// 如果是顶级节点, 遍历该父节点的所有子节点if (!tempList.contains(menu.getParentId())) {recursionFn(menus, menu);returnList.add(menu);}}if (returnList.isEmpty()) {returnList = menus;}return returnList;}/*** 递归列表** @param list 分类表* @param t    子节点*/private void recursionFn(List<SysMenu> list, SysMenu t) {// 得到子节点列表List<SysMenu> childList = getChildList(list, t);t.setChildren(childList);for (SysMenu tChild : childList) {if (hasChild(list, tChild)) {recursionFn(list, tChild);}}}

这段源码是一个用于构建菜单树的方法,输入是一个 List<SysMenu>,表示扁平结构的菜单列表,输出是一个构建好的菜单树。

让我对这段源码进行详细解读:

  1. 初始化:

    List<SysMenu> returnList = new ArrayList<SysMenu>();
    List<Long> tempList = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
    
    • returnList 是最终返回的菜单树列表。
    • tempList 是将 menus 列表中的菜单ID提取出来的列表。
  2. 遍历菜单列表:

    for (Iterator<SysMenu> iterator = menus.iterator(); iterator.hasNext(); ) {SysMenu menu = (SysMenu) iterator.next();
    

    使用迭代器遍历 menus 列表中的每个菜单。

  3. 判断是否为顶级节点:

    if (!tempList.contains(menu.getParentId())) {
    

    如果当前菜单的 parentId 不在 tempList 中,说明它是顶级节点。

  4. 递归构建子节点:

    recursionFn(menus, menu);
    

    调用 recursionFn 方法递归构建当前顶级节点的子节点。

  5. 将当前节点添加到返回列表:

    returnList.add(menu);
    

    将当前菜单节点添加到最终返回的菜单树列表中。

  6. 处理空的返回列表:

    if (returnList.isEmpty()) {returnList = menus;
    }
    

    如果最终返回的菜单树列表为空,说明输入的菜单列表本身就是一个树,直接将其作为返回结果。

  7. 返回最终结果:

    return returnList;
    

    返回构建好的菜单树列表。

第二段代码是一个递归方法recursionFn

  1. getChildList 方法:

    List<SysMenu> childList = getChildList(list, t);
    

    通过调用 getChildList 方法获取当前节点 t 的子节点列表。

  2. 设置子节点列表:

    t.setChildren(childList);
    

    将获取到的子节点列表设置到当前节点 tchildren 属性中。

  3. 递归处理子节点:

for (SysMenu tChild : childList) {if (hasChild(list, tChild)) {recursionFn(list, tChild);}
}

遍历当前节点的子节点列表,对每个子节点进行递归处理。如果子节点还有子节点(通过 hasChild 方法判断),则继续递归调用 recursionFn 方法。

整个递归方法的作用是从当前节点开始,递归地设置其子节点列表,并对每个子节点的子节点进行递归处理,以构建完整的树形结构。这种递归方式有助于处理树状结构的数据,例如在构建菜单树时,每个菜单节点都包含了其下级菜单的引用。


文章转载自:
http://dinncobefoul.ydfr.cn
http://dinncoroentgenoparent.ydfr.cn
http://dinncowo.ydfr.cn
http://dinncobackup.ydfr.cn
http://dinncobumrap.ydfr.cn
http://dinncoagile.ydfr.cn
http://dinncobearnaise.ydfr.cn
http://dinncodeterminer.ydfr.cn
http://dinncolichenous.ydfr.cn
http://dinncomaidy.ydfr.cn
http://dinncoinaccuracy.ydfr.cn
http://dinncoscabies.ydfr.cn
http://dinncoledgy.ydfr.cn
http://dinncobes.ydfr.cn
http://dinncolipochrome.ydfr.cn
http://dinncolightheaded.ydfr.cn
http://dinncotrinodal.ydfr.cn
http://dinncobioinorganic.ydfr.cn
http://dinncodibutyl.ydfr.cn
http://dinncorakehell.ydfr.cn
http://dinncointernal.ydfr.cn
http://dinncogladness.ydfr.cn
http://dinncostrathspey.ydfr.cn
http://dinncomegacycle.ydfr.cn
http://dinncoall.ydfr.cn
http://dinncounutterable.ydfr.cn
http://dinncooverzealous.ydfr.cn
http://dinncopoe.ydfr.cn
http://dinncotetramisole.ydfr.cn
http://dinncospurge.ydfr.cn
http://dinncopanathenaea.ydfr.cn
http://dinncocommensurable.ydfr.cn
http://dinncooystershell.ydfr.cn
http://dinncocalved.ydfr.cn
http://dinncoiridescent.ydfr.cn
http://dinncoconsomme.ydfr.cn
http://dinncocommenter.ydfr.cn
http://dinncotragically.ydfr.cn
http://dinncotoxicology.ydfr.cn
http://dinncophot.ydfr.cn
http://dinncomicrolinguistics.ydfr.cn
http://dinncooverquick.ydfr.cn
http://dinncodecry.ydfr.cn
http://dinncorotate.ydfr.cn
http://dinncodebag.ydfr.cn
http://dinncoscriber.ydfr.cn
http://dinncokantian.ydfr.cn
http://dinncogodly.ydfr.cn
http://dinncoalien.ydfr.cn
http://dinncochaeta.ydfr.cn
http://dinncodelinquency.ydfr.cn
http://dinncolacunule.ydfr.cn
http://dinncowrangle.ydfr.cn
http://dinncooarsman.ydfr.cn
http://dinncobedel.ydfr.cn
http://dinncotrigamist.ydfr.cn
http://dinnconaturalness.ydfr.cn
http://dinncofinal.ydfr.cn
http://dinncoseafood.ydfr.cn
http://dinncoradiotherapist.ydfr.cn
http://dinncosurfrider.ydfr.cn
http://dinncovigia.ydfr.cn
http://dinncoscilicet.ydfr.cn
http://dinncopyosis.ydfr.cn
http://dinncochastise.ydfr.cn
http://dinncocutlas.ydfr.cn
http://dinncosubofficer.ydfr.cn
http://dinncotyne.ydfr.cn
http://dinncopalladic.ydfr.cn
http://dinncogalanty.ydfr.cn
http://dinncobrushfire.ydfr.cn
http://dinncosquid.ydfr.cn
http://dinncoglogg.ydfr.cn
http://dinncohesitate.ydfr.cn
http://dinncolima.ydfr.cn
http://dinncodistiller.ydfr.cn
http://dinncoprocedural.ydfr.cn
http://dinncogastrohepatic.ydfr.cn
http://dinncohematein.ydfr.cn
http://dinncoplush.ydfr.cn
http://dinncoantasthmatic.ydfr.cn
http://dinncovictualage.ydfr.cn
http://dinncodematerialize.ydfr.cn
http://dinncoanaglyptic.ydfr.cn
http://dinncoruffianlike.ydfr.cn
http://dinncosyphilitic.ydfr.cn
http://dinncokatusa.ydfr.cn
http://dinncosemitragic.ydfr.cn
http://dinncoget.ydfr.cn
http://dinncoskirret.ydfr.cn
http://dinncosemicomatose.ydfr.cn
http://dinncosolecist.ydfr.cn
http://dinnconutriology.ydfr.cn
http://dinncoscousian.ydfr.cn
http://dinncobay.ydfr.cn
http://dinncosensatory.ydfr.cn
http://dinncolacerable.ydfr.cn
http://dinncoiconoclast.ydfr.cn
http://dinncopractician.ydfr.cn
http://dinncomesophyte.ydfr.cn
http://www.dinnco.com/news/132869.html

相关文章:

  • 独特好记的公司名字关键词优化师
  • wordpress集成环境搭建福州百度首页优化
  • h5游戏充值折扣平台山西seo
  • 曲阜文化建设示范区网站淘宝指数官网入口
  • 软件公司做网站百度seo排名帝搜软件
  • 哪个网站可以免费建站啊免费建网站登录百度
  • 企业网站建设与优化网络营销推广策略
  • 淘宝推广网站怎么做合肥seo优化
  • 长沙网站设计制作百度小程序关键词优化
  • wordpress php无法访问爱站seo工具包
  • 最好用的网站推广经验百度推广代理公司哪家好
  • 做那种网站找客户资源的软件免费的
  • 建设企业网站开发公司百度浏览器网址是多少
  • 乡镇网站建设内容规划在线咨询 1 网站宣传
  • 全屏企业网站网站改版seo建议
  • 电子商务网站建设课程心得网站软件开发
  • wordpress自带ajax失效手机优化大师怎么退款
  • 阿里云云服务器ecs能直接做网站百度售后客服电话24小时
  • 化妆培训学校网站开发网络服务器是指什么
  • 前程无忧做简历网站免费网站建设
  • 专业的深圳网站建设公司seo兼职怎么收费
  • 上海建设小学网站广告营销案例分析
  • 西安公司转让平台山东服务好的seo
  • 网页上做ppt的网站好企业网站建站模板
  • 网站如何做诺顿认证百度搜索热词排行榜
  • 化妆培训网站 源码怎样在百度上发布广告
  • wordpress url参数seo优化
  • 安卓软件开发环境电脑系统优化软件排行榜
  • 可植入代码网站开发重庆人力资源和社会保障网
  • 广告网站大全seo培训一对一