公司有个业务需要查出所有的课程分类,并将最后一层类别所包含的课查出来。
![image-20220225211048126](https://i-blog.csdnimg.cn/blog_migrate/2e201019c25acdfc829892074fe3b47f.png)
数据库说明,有一个parent_id 字段是最好的:
![image-20220225211845304](https://i-blog.csdnimg.cn/blog_migrate/bf5b0fb9c3244a42ebf82f8d16839221.png)
parent_id的值就是上级的id,一般的话,最顶级的parent_id是设置为0
1.实体类
课程分类:
public class CourseType extends BaseEntity
{
/** 主键 */
private Long id;
/** 类别名称 */
private String name;
}
课程类:
public class Curriculum extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键 */
private Long id;
/** 课程类别 */
private Long courseType;
/** 章节数 */
private Long chapterNum;
/** 课程封面图 */
private String imgUrl;
/** 级别 */
private Integer level;
/** 课程名称 */
private String name;
/** 课程介绍 */
private String introduce;
}
2.涉及的视图VO类
类名不规范 🤒,不要在意
我们需要在类中添加List children,元素类型为该类本身的list
这样套娃就能形成树结构
@Data
public class CourseTypeTree {
private String id;
private String parentId;
private String typeName;
/** 子分类 */
private List<CourseTypeTree> children;
/** 子分类所拥有的课程 */
private List<CurriculumVO> curriculums;
}
3.mapper.xml文件
<!-- 第一步:---------------------------- -->
<!-- Mapper层调用的方法,查出所有顶级类别 -->
<select id="getNodeTree" resultMap="BaseTreeResultMap">
SELECT
*
FROM ty_course_type
WHERE parent_id = 0
</select>
<!-- 第二步:---------------------------- -->
<!-- 通过映射,collection调用查询下一级的方法 -->
<resultMap id="BaseTreeResultMap" type="com.yangfan.ty.domain.CourseTypeTree">
<result column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="typeName"/>
<collection column="id" property="children" javaType="java.util.ArrayList"
ofType="com.yangfan.ty.domain.CourseTypeTree" select="getNextNodeTree"/>
</resultMap>
<!-- 第三步:---------------------------- -->
<!-- 用于查询下一级(会循环调用该查询) -->
<select id="getNextNodeTree" resultMap="NextTreeResultMap">
SELECT
*
FROM ty_course_type
WHERE parent_id = #{id}
</select>
<!-- 第四步:---------------------------- -->
<!-- 通过映射(达到循环查询),继续调用getNextNodeTree查询下一级,直到没有 -->
<!-- 如果你只是想查出数的结构,到这里就可以止步了 -->
<!-- 记号A:----第一个collection是我的业务需求(对应视图的List<CurriculumVO> curriculums),可删除 -->
<resultMap id="NextTreeResultMap" type="com.yangfan.ty.domain.CourseTypeTree">
<result column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="typeName"/>
<collection column="id" property="curriculums" javaType="java.util.ArrayList"
ofType="com.yangfan.ty.domain.vo.CurriculumVO" select="getCurriculumByType"/>
<collection column="id" property="children" javaType="java.util.ArrayList"
ofType="com.yangfan.ty.domain.CourseTypeTree" select="getNextNodeTree"/>
</resultMap>
<!-- 第五步:------------------以下均为业务拓展---- -->
<!-- 执行其它业务查询,如第四步的记号A所诉 -->
<!-- 查询子分类所拥有的课程 -->
<select id="getCurriculumByType" resultMap="curriculumMapA">
select
*
from ty_curriculum
where course_type = #{id}
</select>
<!-- 第六步:---------------------------- -->
<!-- 对查询的结果映射到视图类 -->
<resultMap id="curriculumMapA" type="com.yangfan.ty.domain.vo.CurriculumVO">
<id column="id" property="id"/>
<id column="chapter_num" property="chapterNum"/>
<id column="name" property="name"/>
<id column="introduce" property="introduce"/>
<id column="course_type" property="courseType"/>
<id column="img_url" property="imgUrl"/>
<id column="level" property="level"/>
</resultMap>
效果大概是这样的(children就是下一级,因为数据库没数据所以为null,由于业务更改,顶层的分类单独查询,所以该图没有顶级的数据):
当然这只是一种实现方式,正好遇到这样的业务,所以记录一波。
后面有其他解决办法也会即时更新到此文章