对递归的一点理解

在项目中经常遇到对于部门这种需要设计父id和子id的程序,或者文件夹的处理。对于这一类问题最好的处理方法还应当是递归处理,在这里先回忆一下递归的方面的一些知识:

递归调用:

  • 在一个方法内部对自身的调用就是递归;
  • 递归一定要向已知方向递归,即某时刻返回值是已知的,不然变成了无穷递归

递归程序的内部如图所示:

 

 

在实际的运用中,可以参考博客:https://blog.csdn.net/weixin_44440642/article/details/106331220。博客作者:不知所终,不知所起。

在本篇博客中仅做学习和记录所用。

在数据库中怎么存储呢这种数据?

id parentID name
1 0 手机
2 1 智能手机
3 1 非智能手机
4 2 国产智能手机
5 2 非国产智能手机
6 4 华为
7 4 小米
8 5 苹果
9 5 三星

我们期望的传递的值:

[
  {
    "id": "1",
    "parentid": "0",
    "name": "手机",
    "children": [
      {
        "id": "2",
        "parentid": "1",
        "name": "智能手机",
        "children": [
          {
            "id": "4",
            "parentid": "2",
            "name": "国产智能手机",
            "children": [
              {
                "id": "6",
                "parentid": "4",
                "name": "华为",
                "children": []
              },
              {
                "id": "7",
                "parentid": "4",
                "name": "小米",
                "children": []
              }
            ]
          },
          {
            "id": "5",
            "parentid": "2",
            "name": "非国产智能手机",
            "children": [
              {
                "id": "8",
                "parentid": "5",
                "name": "苹果",
                "children": []
              },
              {
                "id": "9",
                "parentid": "5",
                "name": "三星",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "id": "3",
        "parentid": "1",
        "name": "非智能手机",
        "children": []
      }
    ]
  }
]

实现:

1定义entity类

//数据库内容
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@ApiModel(value="shouji", description="")
public class Shouji implements Serializable {

    private static final long serialVersionUID = 1L;

    @TableId(value = "id", type = IdType.AUTO)
    private String id;

    @TableField("pname")
    private String pname;

    @TableField("parentid")
    private String parentid;

}
//扩展类
@Data
@ToString
public class Shouji Node extends Shouji {

    List<Shouji > children;

}

2.定义mapper

<!--public TeachplanNode selectList(String courseId);-->
    <select id="selectList"  resultType="com.lianxizhifu.springboot.entity.ShoujiNode">
        select * from Shouji
    </select>
List<ShoujiNode> selectList();

3.定义service

List<ShoujiNode> selectList();
  @Override
    public List<ShoujiNode> selectList(String id) {
        //定义得到的结果封装
        List<ShoujiNode> shoujiNodes = shoujiMapper.selectList();
        //递归整理父ID和子ID关系
        List<ShoujiNode> shoujiNodes1 = this.recursionBuildingGroup(shoujiNodes , id);
        return shoujiNodes1 ;
    }

4.具体实现

4.1 方法一使用java代码递归

//递归迭代树型结构
    private List<ShoujiNode> recursionBuildingGroup
                        (List<ShoujiNode> ShoujiNodes, String parentId) {
        //定义接受树型图节点列表
        List<ShoujiNode> sonList = new ArrayList<>();
        //迭代数据得到所有节点
        for (TeachplanNode res : shoujiNodes) {
            //判断此节点的父ID是否等于要得到的节点
            if (res.getParentid().equals(parentId)) {
                //递归调用当前的ID是否存在子节点
                List<ShoujiNode> list = recursionBuildingGroup
                                                (shoujiNodes, res.getId());
                //得到对应的子节点的集合
                res.setChildren(list);
                sonList.add(res);
            }
        }
        return sonList;
    }

4.2方法二使用SQL递归

<resultMap id="teachplanMap" type="com.lianxizhifu.springboot.entity.ShoujiNode">
        <id column="one_id" property="id"></id>
        <result column="one_pname" property="pname"></result>
        <result column="one_parentid" property="parentid"></result>
        <collection property="children" ofType="com.lianxizhifu.springboot.entity.ShoujiNode">
            <id column="tow_id" property="id"></id>
            <result column="tow_pname" property="pname"></result>
            <result column="tow_parentid" property="parentid"></result>
            <collection property="children"  ofType="com.lianxizhifu.springboot.entity.ShoujiNode">
                <id column="thret_id" property="id"></id>
                <result column="thret_pname" property="pname"></result>
                <result column="thret_parentid" property="parentid"></result>
            </collection>
        </collection>
    </resultMap>
    <!--public TeachplanNode selectList(String courseId);-->
    <select id="selectList" parameterType="java.lang.String"
            resultMap="teachplanMap">
        SELECT
        a.id one_id,
        a.pname one_pname,
        a.parentid one_parentid
        b.id tow_id,
        b.pname tow_pname,
        b.parentid tow_parentid
        c.id thret_id,
        c.pname thret_pname,
        c.parentid thret_parentid

        FROM
        teachplan a
        LEFT JOIN shosuji b ON b.parentid = a.id
        LEFT JOIN shosuji c ON c.parentid = b.id
        WHERE
        a.parentid = #{id}

        ORDER BY
        a.orderby,
        b.orderby
    </select>

5.定义controller

  @GetMapping("/selectList/{id}")
    public List<ShoujiNode> selectList(@PathVariable("id") String id) {
        List<ShoujiNode> shoujis= shoujiService.selectList(id);
        return shoujis;
    }

6.结果

[
  {
    "id": "1",
    "parentid": "0",
    "name": "手机",
    "children": [
      {
        "id": "2",
        "parentid": "1",
        "name": "智能手机",
        "children": [
          {
            "id": "4",
            "parentid": "2",
            "name": "国产智能手机",
            "children": [
              {
                "id": "6",
                "parentid": "4",
                "name": "华为",
                "children": []
              },
              {
                "id": "7",
                "parentid": "4",
                "name": "小米",
                "children": []
              }
            ]
          },
          {
            "id": "5",
            "parentid": "2",
            "name": "非国产智能手机",
            "children": [
              {
                "id": "8",
                "parentid": "5",
                "name": "苹果",
                "children": []
              },
              {
                "id": "9",
                "parentid": "5",
                "name": "三星",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "id": "3",
        "parentid": "1",
        "name": "非智能手机",
        "children": []
      }
    ]
  }
]

 

posted @ 2021-05-27 11:19  菜鸟零零发  阅读(79)  评论(0编辑  收藏  举报