05-学成在线课程分类查询

news2024/11/24 7:09:11

课程分类查询

界面原型

在新增课程基本信息界面中课程等级、课程类型、课程分类三处信息需要用户选择

在这里插入图片描述

当我们点击新增课程时,前端会请求内容管理服务中的content/course-category/tree-nodes接口获取课程分类表中的课程分类信息

在这里插入图片描述

响应数据模型

课程分类表course_category是一个树型结构表,通过parantid字段将表中的所有记录组成一个树

`

在内容管理服务的model工程中定义一个CourseCategoryTreeDto类存储课程分类信息中的数据

package com.xuecheng.content.model.dto;
/**
 * @description 课程分类树型结点dto
 * @author Mr.M
 * @date 2022/9/7 15:16
 * @version 1.0
 */
@Data
public class CourseCategoryTreeDto extends CourseCategory implements Serializable {
  // 存储当前节点(根节点的下属节点)的所有子节点
  List<CourseCategoryTreeDto> childrenTreeNodes;
} 

此接口要返回全部课程的分类信息并组成一个树型结构(JSON数组)返回给前端,数组的每个元素是课程分类根节点的子节点,每个子节点又有其对应的字节点

[
    // 根节点的子节点
    {
        // 1-2节点的基本信息
        "id" : "1-2",
        "isLeaf" : null,
        "isShow" : null,
        "label" : "移动开发",
        "name" : "移动开发",
        "orderby" : 2,
        "parentid" : "1",
         // 1-2节点的所有子节点信息
        "childrenTreeNodes" : [
         {
                // 1-2-1节点的子节点信息
                "childrenTreeNodes" : null,
                // 1-2-1节点的基本信息
                "id" : "1-2-1",
                "isLeaf" : null,
                "isShow" : null,
                "label" : "微信开发",
                "name" : "微信开发",
                "orderby" : 1,
                "parentid" : "1-2"
            },
            //1-2节点的其他子节点........
        ]
    },
    {
        // 1-1节点的基本信息
        "id" : "1-1",
        "isLeaf" : null,
        "isShow" : null,
        "label" : "前端开发",
        "name" : "前端开发",
        "orderby" : 1,
        "parentid" : "1" 
         // 1-1节点的子节点
        "childrenTreeNodes" : [
         {
                "childrenTreeNodes" : null,
                "id" : "1-1-1",
                "isLeaf" : null,
                "isShow" : null,
                "label" : "HTML/CSS",
                "name" : "HTML/CSS",
                "orderby" : 1,
                "parentid" : "1-1"
            },  
            //1-1节点的其他子节点........
    	]
    },
	//根节点的其他子节点........
]

接口定义(api工程)

从数据库中查询出根节点下所有的课程分类信息,然后在Java程序中遍历查询到的数据组成一个树形结构对象并返回

package com.xuecheng.content.api;
/**
 * <p>
 * 数据字典 前端控制器
 * </p>
 *
 * @author itcast
 */
@Slf4j
@RestController
@Api(value = "课程分类相关接口", tags = "课程分类相关接口")
public class CourseCategoryController {
    @Resource
    private CourseCategoryService courseCategoryService;
    
    @ApiOperation("课程分类相关接口")
    @GetMapping("/course-category/tree-nodes")
    public List<CourseCategoryTreeDto> queryTreeNodes() {
        return courseCategoryService.queryTreeNodes("1");
    }
}

业务开发(service层)

第一步: 使用表的自连接查询,连接条件为two.parentid = one.id(二级分类的父节点为一级分类),同时one.parentid = 1(一级分类的父节点为根节点)

  • 如果我们有三级分类的话,那么还得继续修改SQL语句
SELECT * FROM 
	course_category one
JOIN 
	course_category two 
ON 
	two.parentid = one.id
WHERE 
	one.parentid = '1'

select
       one.id            one_id,
       one.name          one_name,
       one.parentid      one_parentid,
       one.orderby       one_orderby,
       one.label         one_label,
       two.id            two_id,
       two.name          two_name,
       two.parentid      two_parentid,
       two.orderby       two_orderby,
       two.label         two_label
from 
   	   course_category one
inner join 
   	   course_category two 
on 
   	   one.id = two.parentid
where 
   	   one.parentid = 1 and one.is_show = 1 and two.is_show = 1
order by 
       one.orderby,two.orderby

如果当树的层级不固定时,使用with语法底层是利用MySQL的递归实现,把查询出来的结果再次代入到查询子句中继续查询

WITH RECURSIVE t1 AS (
    # 设置一个递归的初始值
    SELECT 1 AS n
    # UNION ALL 不断将每次递归得到的数据加入到表中
    UNION ALL
    # WHERE n < 5 则是终止条件
    SELECT n + 1 FROM t1 WHERE n < 5
)
SELECCT * FROM t1;
# t1 相当于一个表名
WITH RECURSIVE t1 AS (
    SELECT p.* FROM course_category p WHERE p.id = '1'
    UNION ALL
    SELECT c.* FROM course_category c JOIN t1 on c.parentid = t1.id
)

第二步:编写Mapper接口及其SQL映射文件

public interface CourseCategoryMapper extends BaseMapper<CourseCategory> {
    List<CourseCategoryTreeDto> selectTreeNodes();
}
<select id="selectTreeNodes" parameterType="string" resultMap="com.xuecheng.content.model.dto.CourseCategoryTreeDto">
    WITH RECURSIVE t1 AS (
        SELECT p.* FROM course_category p WHERE p.id = #{id}
        UNION ALL
        SELECT c.* FROM course_category c JOIN t1 WHERE c.parentid = t1.id
    )
    SELECT * FROM t1;
</select>

第三步: 编写Service接口及其实现类,使用Java代码将查询到的课程分类数据组装成树形结构

public interface CourseCategoryService {
    /**
     * 课程分类查询
     * @param id 根节点id
     * @return 根节点下面的所有子节点
     */
    List<CourseCategoryTreeDto> queryTreeNodes(String id);
}
@Slf4j
@Service
public class CourseCategoryServiceImpl implements CourseCategoryService {
    @Autowired
    private CourseCategoryMapper courseCategoryMapper;
    @Override
    public List<CourseCategoryTreeDto> queryTreeNodes(String id) {
        // 获取所有的子节点
        List<CourseCategoryTreeDto> categoryTreeDtos = courseCategoryMapper.selectTreeNodes(id);
        // 定义一个List,作为最终返回的数据
        List<CourseCategoryTreeDto> result = new ArrayList<>();
        // 为了方便找子节点的父节点,这里定义一个HashMap,key是节点的id,value是节点本身
        HashMap<String, CourseCategoryTreeDto> nodeMap = new HashMap<>();
        // 将数据封装到List中,只包括根节点的下属节点(1-1、1-2 ···),这里遍历所有节点
        categoryTreeDtos.stream().forEach(item -> {
            // 这里寻找父节点的直接下属节点(1-1、1-2 ···)
            if (item.getParentid().equals(id)) {
                nodeMap.put(item.getId(), item);
                result.add(item);
            }
            // 获取每个子节点的父节点,对于1-1的父节点1是不在Map集合当中的,所以不需要为父节点1设置ChildrenTreeNodes属性
            String parentid = item.getParentid();
            CourseCategoryTreeDto parentNode = nodeMap.get(parentid);
            // 判断HashMap中是否存在该父节点(按理说必定存在,以防万一)
            if (parentNode != null) {
                // 为父节点设置子节点(将1-1-1设为1-1的子节点)
                List childrenTreeNodes = parentNode.getChildrenTreeNodes();
                // 如果子节点暂时为null,则初始化一下父节点的子节点(给个空集合就行)
                if (childrenTreeNodes == null) {
                    parentNode.setChildrenTreeNodes(new ArrayList<CourseCategoryTreeDto>());
                }
                // 将子节点设置给父节点
                parentNode.getChildrenTreeNodes().add(item);
            }
        });
        // 返回根节点的直接下属节点(1-1、1-2 ···),下属节点已经设置了子节点属性
        return result;
    }
}

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

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

相关文章

文件权限中 chmod、u+x、u、r、w、x分别代表什么

Linux系统中的每个文件和目录都有访问许可权限&#xff0c;如下面所示&#xff1a; 要说清楚问题&#xff0c;我们截取一些内容&#xff1a; ypyubuntu:~$ ls -l drwxr-xr-- 2 ypy ypy 4096 Nov 30 18:33 Desktop/ drwxr-xr-- 2 ypy ypy 4096 Nov 30 18:33 Documen…

Unity之NetCode多人网络游戏联机对战教程(10)--玩家动画同步

文章目录 前言NetworkAnimation服务端权威客户端权威 前言 这次的动画同步与位置同步&#xff0c;可以说实现思路是一样的&#xff0c;代码相似度也非常高 NetworkAnimation 如果直接挂载这个脚本只有Host&#xff08;服务端&#xff09;才可以同步&#xff0c;Client是没有…

迁移redis数据库中的数据到另一台服务器

方案一 下面我使用的redis是用docker安装的&#xff0c;不是通过下载安装包安装的&#xff0c;所以和我安装方式不一样的小伙伴可以不看&#xff0c;因为很多操作是基于docker的 话不多说&#xff0c;直接开搞&#xff01; 1.首先一定要确保两台服务器上面的redis版本要一致…

图解Redis适用场景

Redis以其速度而闻名。 1 业务数据缓存 1.1 通用数据缓存 string&#xff0c;int&#xff0c;list&#xff0c;map。Redis 最常见的用例是缓存对象以加速 Web 应用程序。 此用例中&#xff0c;Redis 将频繁请求的数据存储在内存。允许 Web 服务器快速返回频繁访问的数据。这…

vue day2

1、指令修饰符&#xff1a;.指明一些指令后缀&#xff0c;不同后缀封装不同处理操作 按键修饰符&#xff1a;keyup.enter v-model修饰符&#xff1a; v-model.trim&#xff1a;去首位空格 v-model.number&#xff1a;转数字 事件修饰符&#xff1a; 阻止事件冒泡&#xff1…

机器人制作开源方案 | 网球自动拾取机

作者&#xff1a;柳文浩、李浩杰、苏伟男、贾思萌、张天芸 单位&#xff1a;西安外事学院 指导老师&#xff1a;胡宝权、陈小虎 1. 产品说明 1.1 设计目的 近年来&#xff0c;网球运动越来越受到老百姓的欢迎&#xff0c;各种规模的比赛层出不穷。然而由于网球运动极为激烈…

滴滴昨晚崩了,看这波还敢不敢降本增效?

起因 截至 2023 年 11 月 27 日晚&#xff0c;中国最大的网约车服务平台滴滴打车遭遇系统崩溃&#xff0c;继阿里云控制台故障之后&#xff0c;再次引发热议。这一事件迅速攀升至热搜榜首&#xff0c;引起广泛关注。 今晚约 10 点&#xff0c;滴滴打车遭遇大范围技术故障。用户…

Spring的三种常见Bean的初始化参数机制,你都用对了吗?

大家好&#xff0c;我是G探险者。 spring这本九阳神功秘籍&#xff0c;我们一点一滴去研读。 在Spring框架中&#xff0c;Bean的实例化与初始化是一个复杂的过程&#xff0c;一个Bean的实例化过程往往伴随着一些属性的初始化动作&#xff0c;有的是在Bean实例化之后才进行的属…

解决VMware VCenter存储上传镜像文件失败

VMware VCSA6.7上传共享文件时提示操作失败&#xff0c;由于不确定的原因&#xff0c;操作失败。通常&#xff0c;当浏览器不信任证书时会发生此问题。如果您使用的是自签名证书或自定义证书&#xff0c;请在新的浏览器选项卡中打开下面的 URL并接受证书&#xff0c;然后重试操…

五、Lua流程控制与函数

一、流程控制 &#xff08;一&#xff09;含义 Lua 编程语言流程控制语句通过程序设定一个或多个条件语句来设定。在条件为 true 时执行指定程序代码&#xff0c;在条件为 false 时执行其他指定代码。 &#xff08;二&#xff09;原型 if (成立) then执行体1else执行体2 end…

蓝桥杯每日一题2023.11.27

题目描述 星系炸弹 - 蓝桥云课 (lanqiao.cn) 题目分析 对于此题目一一枚举即可 #include<bits/stdc.h> using namespace std; bool is_r(int n) {if((n % 4 0 && n % 100 ! 0)|| n % 400 0)return true;return false; } int mm[13] {0, 31, 28, 31, 30, 3…

智能优化算法应用:基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于樽海鞘群算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.樽海鞘群算法4.实验参数设定5.算法结果6.参考…

图像分类任务

本文记录 北京邮电大学 计算机学院的学习记录 什么是图像分类任务&#xff1f; 图像分类任务是计算机视觉中的核心任务&#xff0c;其目 标是根据图像信息中所反映的不同特征&#xff0c;把不同类别 的图像区分开来 图像分类任务有哪些难点呢&#xff1f; 语义鸿沟视角变化…

【springboot】宝塔简单部署springboot 配置https

宝塔简单部署springboot配置https 需求步骤1. springboot通过maven组件打成jar包2. 将jar包部署到宝塔上3. 下载安装nginx并创建网站节点4. 设置域名或者IP5. 设置反向代理:代理后端服务的ip和端口7. 配置SSL/TLS 需求 宝塔部署springboot项目,用nginx反向代理后端IP端口&…

用Elasticsearch搜索匹配功能实现基于地理位置的查询

1.Redis,MongoDB,Elasticsearch实现地理位置查询比较 1.1 Redis: 优点&#xff1a;Redis提供了地理空间索引功能&#xff0c;可以通过Geo数据类型进行地理位置查询。这使得Redis在处理地理位置查询时非常高效。 缺点&#xff1a; Redis的地理空间索引功能相对简单&#xff0…

【单调栈】最大宽度坡

public int maxWidthRamp(int[] nums) {/* 此方法思路正确&#xff0c;但超时int n nums.length;Deque<Integer> stack;int max 0;for (int i 0; i < n; i) {stack new LinkedList<>();stack.push(nums[i]);int j i 1;while (j < n) {stack.push(nums…

华为拆分零部件业务,长安入股,赛力斯接洽中

作者 |德新 编辑 |王博 11月26日&#xff0c;长安汽车官宣与华为在智能汽车零部件业务上的投资与合作&#xff1a; 华为拟成立一家新的公司&#xff0c;并将其在智能汽车解决方案业务上的核心技术和资源注入新公司&#xff0c;长安汽车及关联方有意投资该新公司。 参照目前长…

如何保护PPT文件禁止修改?

PPT文件会应用在会议、演讲、课件等工作生活中&#xff0c;当我们制作好了PPT之后&#xff0c;保护内容防止在演示时出错是很重要的&#xff0c;那么如何将PPT文件设置成禁止修改模式呢&#xff1f;今天分享几个方法给大家。 方法一 将PPT文件直接保存或者另存为一份文件&…

Gitea和Jenkins安装

Gitea Gitea&#xff1a;https://dl.gitea.com/gitea/1.21.0/ Jenkins&#xff1a;https://www.jenkins.io/download/ 数据库配置 可以参考官方文档-https://docs.gitea.cn/1.20/installation/database-prep&#xff0c;这里以MySQL作为讲解 MySQL 在数据库实例上&#xf…

小航助学题库蓝桥杯题库stem选拔赛(21年1月)(含题库教师学生账号)

需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSDN博客 需要在线模拟训练的题库账号请点击 小航助学编程在线模拟试卷系统&#xff08;含题库答题软件账号&#xff09;_程序猿下山的博客-CSD…