【项目】Java树形结构集合分页,java对list集合进行分页

news2025/8/6 3:52:13

Java树形结构集合分页

    • 需求
    • 难点
    • 实现
      • 第一步:查出所有树形集合数据 (需进行缓存处理)
          • selectTree 方法步骤:
          • TreeUtil类:
      • 第二步:分页 GoodsCategoryController
          • 分页
          • getGoodsCategoryTree方法步骤:
      • 第三步:前端实现
    • 效果图:

需求

商品类目树数据量大导致加载太慢,需添加一个分页功能。
在这里插入图片描述

难点

  • 树状结构不能用mybatis-plus自带的分页功能,需自己写分页逻辑
  • 因数据量大,需进行缓存处理

实现

第一步:查出所有树形集合数据 (需进行缓存处理)

List<GoodsCategoryTree> resultList = goodsCategoryService.selectTree(null);
    List<GoodsCategoryTree> selectTree(GoodsCategory goodsCategory);
selectTree 方法步骤:

判断key是否存在,如果存在,直接取缓存的值 ,不存在就从数据库查出数据,并把值存到redis里。

    @Override
    public List<GoodsCategoryTree> selectTree(GoodsCategory goodsCategory) {
		if(redisTemplate.hasKey(CacheConstants.GOODS_CATEGORY_TREE_KEY)){
			log.info("商品类目管理 selectTree cache");
			List<GoodsCategoryTree> cacheList = SpringUtils.getBean(RedisCache.class).getCacheList(CacheConstants.GOODS_CATEGORY_TREE_KEY);
			return cacheList;
		}
		log.info("商品类目管理 selectTree db");
		List<GoodsCategoryTree> treeList = getTree(this.list(Wrappers.lambdaQuery(goodsCategory)));
		if (CollUtil.isNotEmpty(treeList)){
			SpringUtils.getBean(RedisCache.class).setCacheList(CacheConstants.GOODS_CATEGORY_TREE_KEY,treeList);
		}
        return treeList;
    }

其中 getTree()如下:

	/**
     * @Description: 构建树
     */
    private List<GoodsCategoryTree> getTree(List<GoodsCategory> entitys) {
        List<GoodsCategoryTree> treeList = entitys.stream()
                .filter(entity -> !entity.getId().equals(entity.getParentId()))
                .sorted(Comparator.comparingInt(GoodsCategory::getSort))
                .map(entity -> {
                    GoodsCategoryTree node = new GoodsCategoryTree();
                    BeanUtil.copyProperties(entity, node);
                    return node;
                }).collect(Collectors.toList());
        return TreeUtil.build(treeList, CommonConstants.PARENT_ID);
    }
TreeUtil类:
@UtilityClass
public class TreeUtil {
	/**
	 * 两层循环实现建树
	 *
	 * @param treeNodes 传入的树节点列表
	 * @return
	 */
	public <T extends TreeNode> List<T> build(List<T> treeNodes, Object root) {
		List<T> trees = new ArrayList<>();
		for (T treeNode : treeNodes) {
			if (root.equals(treeNode.getParentId())) {
				trees.add(treeNode);
//				trees.sort(Comparator.comparing(TreeNode::getSort));
			}
			for (T it : treeNodes) {
				if (it.getParentId().equals(treeNode.getId())) {
					treeNode.addChildren(it);
//					treeNode.getChildren().sort(Comparator.comparing(TreeNode::getSort));
				}
			}
		}
		return trees;
	}
}

第二步:分页 GoodsCategoryController

	/**
	 * 返回树形集合分页数据
	 *
	 * @return
	 */
	@ApiOperation(value = "返回树形集合分页数据")
	@GetMapping("/treePage")
	public R getGoodsCategoryTree(Page page, GoodsCategory goodsCategory) {
		//得到所有数据
		List<GoodsCategoryTree> resultList = goodsCategoryService.selectTree(null);
		if (resultList != null && resultList.size() > 0) {
			page.setTotal(resultList.size());
		}
		//分页
		List<GoodsCategoryTree> finalList =  goodsCategoryService.getFinalListByPage(page,resultList);

		if (finalList != null && finalList.size() > 0) {
			page.setRecords(finalList);
		}
		return R.ok(page);
	}
分页
	/** 分页查询类目树
	 */

	List<GoodsCategoryTree> getFinalListByPage(Page page , List<GoodsCategoryTree> resultList );
getGoodsCategoryTree方法步骤:

参考:java对list集合进行分页
首先把数据根据创建时间倒序排列,再进行分页

	@Override
	public List<GoodsCategoryTree> getFinalListByPage(Page page, List<GoodsCategoryTree> resultList) {
		//根据创建时间倒序排列
		List<GoodsCategoryTree> treeList = resultList.stream().sorted(Comparator.comparing(GoodsCategoryTree::getCreateTime).reversed())
				.collect(Collectors.toList());
        //进行分页
		List<GoodsCategoryTree> subList = treeList.stream().skip((page.getCurrent()-1)*page.getSize()).limit(page.getSize()).
				collect(Collectors.toList());
		return subList;
	}

第三步:前端实现

avue-crud 组件加上:page.sync=“page”

      <avue-crud
        ref="crud"
        :data="tableData"
        :page.sync="page"
        :permission="permissionList"
        :table-loading="tableLoading"
        :option="tableOption"
        :before-open="beforeOpen"
        v-model="form"
        @on-load="getPage"
        @refresh-change="refreshChange"
        @row-update="handleUpdate"
        @row-save="handleSave"
        @row-del="handleDel"
      >

data() 加上:

      page: {
        total: 0, // 总页数
        currentPage: 1, // 当前页数
        pageSize: 20, // 每页显示多少条
        ascs: [], //升序字段
        descs: "create_time", //降序字段
      },
      paramsSearch: {},
      date: [],
      
    };

重写getPage()方法:

getPage(page, params) {
      this.tableLoading = true;
      fetchTree(
        Object.assign(
          {
            current: page.currentPage,
            size: page.pageSize,
            descs: this.page.descs,
            ascs: this.page.ascs,
            beginTime: this.date[0],
            endTime: this.date[1],
          },
          params,
          this.paramsSearch
        )
      )
        .then((response) => {
          let tableData = response.data.data.records;
          this.tableData = tableData;
          this.page.total = response.data.data.total;
          this.page.currentPage = page.currentPage;
          this.page.pageSize = page.pageSize;
          let parentIdDIC = [
            {
              id: "0",
              name: "顶级分类",
              parentId: "0",
            },
          ];
          tableData.forEach((item) => {
            parentIdDIC.push({
              id: item.id,
              name: item.name,
              parentId: item.parentId,
            });
          });
          this.$refs.crud.DIC.parentId = parentIdDIC;
          this.tableLoading = false;
        })
        .catch(() => {
          this.tableLoading = false;
        });
    },

效果图:

在这里插入图片描述

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

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

相关文章

MySQL数据库基本操作-DQL

概念 数据库管理系统一个重要功能就是数据查询&#xff0c;数据查询不应只是简单返回数据库中存储的数据&#xff0c;还应该根据需要对数据进行筛选以及确定数据以什么样的格式显示。 MySQL提供了功能强大、灵活的语句来实现这些操作。 MySQL数据库使用select语句来查询数据 语…

ansible组件介绍和简单playbook测试

一、ansible inventory 在大规模的配置管理工作中&#xff0c;管理不同业务的机器&#xff0c;机器的信息都存放在ansible的inventory组件里面。在工作中&#xff0c;配置部署针对的主机必须先存放在Inventory里面&#xff0c;然后ansible才能对它进行操作。默认的Ansible的in…

docker常用命令,基于linux+centos7

启动docker systemctl start docker 重启docker systemctl restart docker docker自启动 systemctl enable docker 查看所有docker&#xff0c;包括正在运行的和关闭的 docker ps -a 查看正在运行的docker docker ps 停止正在运行的docker。通过id或者docker名称 do…

Ceph介绍

分布式存储概述 常用的存储可以分为DAS、NAS和SAN三类 DAS&#xff1a;直接连接存储&#xff0c;是指通过SCSI接口或FC接口直接连接到一台计算机上&#xff0c;常见的就是服务器的硬盘NAS&#xff1a;网络附加存储&#xff0c;是指将存储设备通过标准的网络拓扑结构&#xff…

client打包升级

目录 前言 一、client如何打包升级&#xff1f; 二、使用步骤 1.先进行改版本 2.执行打包升级命令 总结 前言 本文章主要记录一下&#xff0c;日常开发中&#xff0c;常需要进行打包升级的步骤。 一、client如何打包升级&#xff1f; # 升级发布版本 ## 修改版本 * 父p…

链表经典面试题【典中典】

&#x1f4af;&#x1f4af;&#x1f4af;链表经典面试题❗❗❗炒鸡经典&#xff0c;本篇带有图文解析&#xff0c;建议动手刷几遍。&#x1f7e5;1.反转链表&#x1f7e7;2.合并两个有序链表&#x1f7e8;3.链表分割&#x1f7e9;4.链表的回文结构&#x1f7e6;5.相交链表&…

74. ‘pip‘不是内部或外部命令,也不是可运行的程序-解决办法

74. pip’不是内部或外部命令&#xff0c;也不是可运行的程序-解决办法 文章目录74. pip不是内部或外部命令&#xff0c;也不是可运行的程序-解决办法1. 课题导入2. 手动配置环境变量1. 准备工作2. 配置步骤3. 命令行安装1. 课题导入 有的同学在使用pip安装第三方库时&#xf…

elasticsearch 分布式搜索引擎1

1.初识elasticsearch 1.1.了解ES 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速找到需要的内容 例如&#xff1a; 在GitHub搜索代码 在电商网站搜索商品 在百度搜索答案 在…

WorksPace一款简化修改IP繁琐重复性工作的高效工具

WorksPace简介 workspace软件中文版是一个集成修改网卡IP、网络扫描、记事本、快速启动的效率工具&#xff0c;前端使用Flutter&#xff0c;后端主要是Dart&#xff0c;少量的后台功能用以前Golang&#xff0c;数据存储使用SQLite。主要是为了简化我在日常工作中的频繁重复操作…

app里未读消息已读、未读是怎么设计的?

也不知道大家目前都用的java编程软件有哪些&#xff0c;毕竟在应用程序中&#xff0c;未读和已读消息的设计取决于应用程序的需求和目标。下面是一些常见的设计模式&#xff1a;一、简单的未读/已读标记简单的未读/已读标记&#xff1a;这是最常见的设计&#xff0c;用户打开应…

Linux - Linux系统优化思路

文章目录影响Linux性能的因素CPU内存磁盘I/O性能网络宽带操作系统相关资源系统安装优化内核参数优化文件系统优化应用程序软件资源系统性能分析工具vmstat命令iostat命令sar命令系统性能分析标准小结影响Linux性能的因素 CPU CPU是操作系统稳定运行的根本&#xff0c;CPU的速…

一元导数与多元求导数总结

前序&#xff1a;文章结构 1.一元导数 ①一般函数求导 因为太简单的原因&#xff0c;事实上一般函数求导不会单独出现&#xff0c;大多数都是出现在各种特殊的求导过程中。只要掌握16个基本求导公式没问题。 ②复合函数求导&#xff08;主要链式法则&#xff09; 这种一般是…

流量监管与整形

流量监管与整形概览流量监管介绍流量监管令牌桶流量监管的具体实现单桶单速流量监管双桶单速流量监管双桶双速流量监管流量整形介绍GTS&#xff08;Generic Traffic Shaping&#xff09;LR&#xff08;Line Rate&#xff09;流量整形与流量监管的区别概览 流量整形是对报文的速…

某美颜app sig参数分析

之前转载过该app的文章&#xff0c;今天翻版重新整理下&#xff0c;版本号:576O5Zu56eA56eAYXBwIHY5MDgw (base64 解码)。 上来先抓个包&#xff1a; jadx搜索关键词 "sigTime"&#xff0c;然后定位到这里 看这行代码 cVar.addForm(INoCaptchaComponent.sig, genera…

NAST概述

一、NATS介绍 NATS是由CloudFoundry的架构师Derek开发的一个开源的、轻量级、高性能的&#xff0c;支持发布、订阅机制的分布式消息队列系统。它的核心基于EventMachine开发&#xff0c;代码量不多&#xff0c;可以下载下来慢慢研究。 不同于Java社区的kafka&#xff0c;nats…

C++小白入门

1.1编写程序四步走&#xff1a;创建项目创建文件编写代码运行程序解决方案资源管理器&#xff1a;在新创建的项目下右键“源文件”-添加-“新建项”-“C文件&#xff08;.cpp&#xff09;”&#xff0c;给文件取名#include <iostream> using namespace std;int main() {c…

JavaScript新手学习手册-基础代码(二)

与上篇博客相接 一&#xff1a;函数&#xff1a; 案例&#xff1a;通过函数实现绝对值的输出 方法一&#xff1a; function absoluate(x){if(x>0){return x;}else{ return -x;}} 在控制台调用函数 方法二&#xff1a; var demo1 function(x){if(x>0){return x;}els…

springboot项目如何配置启动端口

文章目录0 写在前面1 配置文件(.yaml)--推荐2 配置文件(.properties)3 IDEA配置--不推荐4 写在最后0 写在前面 项目启动需要一个独立的端口&#xff0c;所以在此记录一下。 根据配置文件的后缀书写格式略有不同。 1 配置文件(.yaml)–推荐 若是.yaml后缀的配置文件&#xff0…

SIP网络定压功放 SIP735T机架式广播终端

一、描述SIP735T是广州新悦网络设备有限公司的一款合并式定压功放&#xff0c;支持标准SIP协议&#xff0c;具有10/100M以太网接口&#xff0c;后面板上有2组AUX音源输入和6.35mm接口的麦克风输入&#xff0c;可以输入本地音源&#xff0c;播放来自网络与本地的音频。同时配置5…

Spark UI

Spark UIExecutorsEnvironmentStorageSQLExchangeSortAggregateJobsStagesStage DAGEvent TimelineTask MetricsSummary MetricsTasks展示 Spark UI &#xff0c;需要设置配置项并启动 History Server # SPARK_HOME表示Spark安装目录 ${SPAK_HOME}/sbin/start-history-server…