springBoot学习笔记(2.2)—— 整合mybatis之递归子查询

前言

提示:前两篇文章研究了spring Boot整合mybaits,现在这篇文章研究mybatis中递归子查询的问题。至于编写application.yml配置文件此次不再赘述

一、搭建步骤

1.构建实体类和表结构

  1. @Data
  2. public class Dept {
  3. /**
  4. * 主键id
  5. */
  6. private Long id;
  7. /**
  8. * 部门名称
  9. */
  10. private String deptName;
  11. /**
  12. * 父类id
  13. */
  14. private Long parentId;
  15. /**
  16. * 排序码
  17. */
  18. private String orderCode;
  19. /**
  20. * 是否开启使用(0否,1是)
  21. */
  22. private Integer isStart;
  23. /**
  24. * 说明
  25. */
  26. private String description;
  27. /**
  28. * 地址
  29. */
  30. private String address;
  31. /**
  32. * 人员数据
  33. */
  34. private List<User> userList;
  35. }
  1. CREATE TABLE dept(
  2. id BIGINT (15) NOT NULL AUTO_INCREMENT COMMENT '主键id',
  3. dept_name VARCHAR (50) NOT NULL DEFAULT '' COMMENT '部门名称',
  4. parent_id VARCHAR (50) NOT NULL DEFAULT '' COMMENT '父类id',
  5. order_code VARCHAR (50) NOT NULL DEFAULT '' COMMENT '排序码',
  6. is_start INT (11) NOT NULL DEFAULT 0 COMMENT '是否开启使用(0否,1是)',
  7. description VARCHAR (50) NOT NULL DEFAULT '' COMMENT '说明',
  8. address VARCHAR (50) NOT NULL DEFAULT '' COMMENT '地址',
  9. PRIMARY KEY (id)
  10. )ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT 'dept';

部门表根据id和parent_id 相互关联,表数据可以自己构建,此处不单独引入。

2.Dao接口详情

  1. * description: 递归查询树状数据
  2. * version: 1.0
  3. * date: 2021/12/31 15:09
  4. * author: xiaYZ
  5. * iteration: 迭代说明
  6. * @param
  7. * @return
  8. */
  9. List<Dept> findDeptTreeData();

3. Mapper文件内容 (重点)

  1. <resultMap id="deptTreeMap" type="com.example.springbootmybatis.entity.Dept">
  2. <id column="id" property="id"/>
  3. <result column="dept_name" property="deptName"/>
  4. <result column="parent_id" property="parentId"/>
  5. <result column="order_code" property="orderCode"/>
  6. <result column="is_start" property="isStart"/>
  7. <result column="description" property="description"/>
  8. <result column="address" property="address"/>
  9. <!--递归子查询,findDeptTreeData方法中传入的id,为findChildren中的入参-->
  10. <collection property="children" column="id" ofType="com.example.springbootmybatis.entity.Dept" select="findChildren"/>
  11. </resultMap>
  12. <select id="findDeptTreeData" resultMap="deptTreeMap">
  13. select d.id, dept_name, parent_id, order_code, is_start, description, address
  14. from dept d where parent_id = 0
  15. </select>
  16. <!--如果只需要查询两级分类数据的话可以不使用resultMap="deptTreeMap",使用Dept类即可-->
  17. <select id="findChildren" resultMap="deptTreeMap">
  18. select d.id, dept_name, parent_id, order_code, is_start, description, address
  19. from dept d
  20. where parent_id = #{id}
  21. </select>

4.service层方法

  1. public List<Dept> findDeptTreeData(){
  2. return deptDao.findDeptTreeData();
  3. }

5.controller层方法

  1. /***
  2. * description: 查询部门列表树状数据
  3. * version: 1.0 ->
  4. * date: 2021/12/31 15:19
  5. * author: xiaYZ
  6. * iteration: 迭代说明
  7. * @param
  8. * @return java.util.List<com.example.springbootmybatis.entity.Dept>
  9. */
  10. @GetMapping("findDeptTreeData")
  11. public List<Dept> findDeptTreeData() {
  12. List<Dept> deptList = new ArrayList<>();
  13. try{
  14. deptList = deptService.findDeptTreeData();
  15. }catch (Exception e){
  16. e.printStackTrace();
  17. }
  18. return deptList;
  19. }

6.运行截图

springBoot学习笔记(2.2)—— 整合mybatis之递归子查询 - 图1
注意:

  1. 使用此种方法可能会增大数据压力,一个方法会递归查询所有部门数据。
  2. 如果此处不想让数据库压力过大,可以先把所有部门数据查出来再通过递归方法构建出树状数据类型。

二、使用递归算法构建树状数据

1.mapper内容

  1. <!--查询所有部门数据-->
  2. <select id="findAllDeptData" resultMap="deptMap">
  3. select d.id, dept_name, parent_id, order_code, is_start, description, address
  4. from dept d
  5. </select>

2.service层中算法

  1. public List<Dept> recursionFindDeptTreeData(){
  2. List<Dept> allDeptData = deptDao.findAllDeptData();
  3. return recursionWay(allDeptData, 0L);
  4. }
  5. /**
  6. * 获取子类递归算法
  7. */
  8. public List<Dept> recursionWay(List<Dept> deptList,Long parentId){
  9. List<Dept> childrenDept = new ArrayList<>();
  10. for(Dept sonDept : deptList){
  11. if(Objects.equals(parentId,sonDept.getParentId())){
  12. childrenDept.add(sonDept);
  13. sonDept.setChildren(recursionWay(deptList,sonDept.getId()));
  14. }
  15. }
  16. if(CollectionUtil.isEmpty(deptList)){
  17. return null;
  18. }
  19. return childrenDept;
  20. }

总结

  1. 使用collection标签递归查询子类数据。
  2. 或者先查询所有数据,再使用递归子类算法查询树状数据。

项目源码