“This is the second day of my participation in the Gwen Challenge in November. See details: The Last Gwen Challenge in 2021”

preface

I don’t know if you’ve had any contact with General During the projectplainData processing intoHave a levelThe data is similar to the followingOr life is everywhere, I think you should have touched it, let’s go to the implementation, I’ll talk about the idea, of course, can skip to the end to seecodeImplementation of ha

Follow me! Go go go!

โ— This article is just a simple learning record, not a detailed explanation of the code

๐Ÿ˜Ž Implementation idea ๐Ÿ˜Ž

First of all, the general database model design is as follows

SQL script


-- ----------------------------
-- Table structure for product
-- ----------------------------
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `uuid` varchar(64) NOT NULL,
  `name` varchar(100) NOT NULL COMMENT 'name',
  `sort` int(11) DEFAULT NULL COMMENT 'order',
  `parent_uuid` varchar(64) NOT NULL DEFAULT '1' COMMENT 'Fatherless equals -1',
  `level` varchar(10) NOT NULL COMMENT 'Product hierarchy',
  `create_time` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COMMENT='Product list';

-- ----------------------------
-- Records of product
-- ----------------------------
INSERT INTO `product` VALUES ('1'.'4dbf40d2-2af7-425c-a103-0349caaa26cf'.'Production class'.'1'.'1'.'1'.'the 2021-09-23 15:34:36');
INSERT INTO `product` VALUES ('2'.'3062deff-8ec7-44c4-bd4e-88fe3c7b835c'.'22'.'1'.'4dbf40d2-2af7-425c-a103-0349caaa26cf'.'2'.'the 2021-09-23 15:37:20');
INSERT INTO `product` VALUES ('3'.'32afe426-9337-41c1-83e8-caf3248ba57e'.'Internet information'.'2'.'4dbf40d2-2af7-425c-a103-0349caaa26cf'.'2'.'the 2021-09-23 15:38:19');
INSERT INTO `product` VALUES ('4'.'34c5239f-db2d-4394-b367-a57f8ae6f8ff'.'33'.'1'.'3062deff-8ec7-44c4-bd4e-88fe3c7b835c'.'3'.'the 2021-09-23 15:53:29');
INSERT INTO `product` VALUES ('5'.'19eedcd3-aa7f-4a2d-8182-d3f795e99b9d'.'44'.'1'.'34c5239f-db2d-4394-b367-a57f8ae6f8ff'.'4'.'the 2021-09-23 15:53:56');

Copy the code

Parent_uuid: name: uuid: parent_uuid: UUID, short for Universally Unique Identifier, is a software standard designed to ensure that all elements in a distributed system have Unique identification information, without the need for a central controller to specify identification information. Parent_uuid: the UUID of a subclass whose superclass is -1 (this can be defined as a unique identifier similar to but not equal to ID).

Here is the simulation data I createdIf you want to achieve the number shape structure, you must take a certain attribute as a breakthrough, it isparent_uuidSo how does that work in the actual code

๐Ÿงก Full code ๐Ÿงก

Post only the key code

First, Mabatis- Generator is used to generate the general back-end code, the structure is as follows:

ProductController.class

package com.csdn.caicai.test.modules.product.controller; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import com.csdn.caicai.test.modules.product.dto.ProductRsp; import com.csdn.caicai.test.modules.product.biz.IProductBiz; import java.util.List; /** * Product table ** @author * @date */ @restController@API (tags = {"Product List"})
@RequestMapping("/caicai/product")
@Validated
public class ProductController {
    private static final Logger log= LoggerFactory.getLogger(ProductController.class); @Autowired private IProductBiz productBiz; /** * product tree */ @apiOperation (value ="Product tree")
    @RequestMapping(path = "/tree", method = RequestMethod.GET)
    public List<ProductRsp> tree() {
        returnproductBiz.tree(); }}Copy the code

IProductBiz.class

package com.csdn.caicai.test.modules.product.biz;


import com.csdn.caicai.test.modules.product.dto.ProductRsp;

import java.util.List;

/**
 * @author
 * @date
 */
public interface IProductBiz {


    List<ProductRsp> tree();
}

Copy the code

ProductBiz.class

package com.csdn.caicai.test.modules.product.biz;


import org.apache.commons.lang3.StringUtils;
import org.assertj.core.util.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.stream.Collectors;

import tk.mybatis.mapper.entity.Example;

import com.csdn.caicai.test.modules.product.service.IProductService;
import com.csdn.caicai.test.modules.product.dao.entity.ProductEntity;
import com.csdn.caicai.test.modules.product.dto.ProductReq;
import com.csdn.caicai.test.modules.product.dto.ProductRsp;

import static java.util.stream.Collectors.toList;

/**
 * @author
 * @date
 */
@Service("productBiz") public class ProductBiz implements IProductBiz { @Autowired private IProductService productService; /** ** query ** @param productReq * @return*/ public List<ProductEntity> selectByCondition(ProductReq productReq) { Example example = new Example(ProductEntity.class); // Add custom call criteria belowreturn productService.selectByExample(example);
    }

    @Override
    public List<ProductRsp> tree() {
        ProductReq req = new ProductReq();
        List<ProductRsp> list = selectByCondition(req).stream().map(this::productConvert).collect(Collectors.toList());
        return buildTree(list, req.getParentUuid());
    }

    private ProductRsp productConvert(ProductEntity e) {
        ProductRsp orgNode = new ProductRsp();
        orgNode.setId(e.getId());
        orgNode.setUuid(e.getUuid());
        orgNode.setName(e.getName());
        orgNode.setLevel(e.getLevel());
        orgNode.setSort(e.getSort());
        orgNode.setParentUuid(e.getParentUuid());
        return orgNode;
    }

    public static List<ProductRsp> buildTree(List<ProductRsp> all, String parentUuid) {
        if (CollectionUtils.isEmpty(all))
            return Lists.newArrayList();

        List<ProductRsp> parentList = all.stream()
                .filter(e -> StringUtils.isBlank(e.getParentUuid())
                        || "1".equals(e.getParentUuid())
                        || e.getParentUuid().equals(parentUuid))
                .collect(toList());

        getSubList(parentList, all);

        return parentList;
    }

    private static void getSubList(List<ProductRsp> parentList, List<ProductRsp> all) {
        parentList.forEach(e -> {
            List<ProductRsp> subList = all.stream().filter(o -> o.getParentUuid().equals(e.getUuid())).collect(toList());
            e.setSubList(subList);
            if (!CollectionUtils.isEmpty(subList))
                getSubList(subList, all);
        });
    }
}

Copy the code

ProductReq.class

package com.csdn.caicai.test.modules.product.dto;



import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

/**
* @author
* @date
*/
@ApiModel(value = "ProductReq", description = "Product List")
@Data
public class ProductReq implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
     *
     */
    @ApiModelProperty(value = "", name = "id")
    private Long id;
	/**
     *
     */
    @ApiModelProperty(value = "", name = "uuid") private String uuid; /** * name */ @apiModelProperty (value ="Name", name = "name") private String name; /** * sort */ @apiModelProperty (value ="Order", name = "sort") private Integer sort; /** * the parent level is -1 */ @apiModelProperty (value ="Fatherless equals -1.", name = "parentUuid") private String parentUuid; /** * product level */ @apiModelProperty (value ="Product level", name = "level")
    private String level;
}


Copy the code

ProductRsp.class

package com.csdn.caicai.test.modules.product.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;

import java.util.Date;
import java.util.List;

/**
* @author
* @date
*/
@ApiModel(value = "ProductRsp", description = "Product List")
@Data
public class ProductRsp implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
     *
     */
    @ApiModelProperty(value = "", name = "id")
    private Long id;
	/**
     *
     */
    @ApiModelProperty(value = "", name = "uuid") private String uuid; /** * name */ @apiModelProperty (value ="Name", name = "name") private String name; /** * sort */ @apiModelProperty (value ="Order", name = "sort") private Integer sort; /** * the parent level is -1 */ @apiModelProperty (value ="Fatherless equals -1.", name = "parentUuid") private String parentUuid; /** * product level */ @apiModelProperty (value ="Product level", name = "level")
    private String level;
	/**
     *
     */
    @ApiModelProperty(value = "", name = "createTime")
    private Date createTime;

    @ApiModelProperty(value = "Subordinate Products", name = "subList")
    private List<ProductRsp> subList;
}

Copy the code

Test the As you can see, it implements ourThe effect

๐Ÿ˜œ Summary – Core code ๐Ÿ˜œ

Above rory, in fact, the core code is the following code, pro to try to understand it, and then you can beautify it on this basis: ProductRsp, ProductReq is an entity class, can replace the contents of their own

  private ProductRsp productConvert(ProductEntity e) {
        ProductRsp orgNode = new ProductRsp();
        orgNode.setId(e.getId());
        orgNode.setUuid(e.getUuid());
        orgNode.setName(e.getName());
        orgNode.setLevel(e.getLevel());
        orgNode.setSort(e.getSort());
        orgNode.setParentUuid(e.getParentUuid());
        return orgNode;
    }

    public static List<ProductRsp> buildTree(List<ProductRsp> all, String parentUuid) {
        if (CollectionUtils.isEmpty(all))
            return Lists.newArrayList();

        List<ProductRsp> parentList = all.stream()
                .filter(e -> StringUtils.isBlank(e.getParentUuid())
                        || "1".equals(e.getParentUuid())
                        || e.getParentUuid().equals(parentUuid))
                .collect(toList());

        getSubList(parentList, all);

        return parentList;
    }

    private static void getSubList(List<ProductRsp> parentList, List<ProductRsp> all) {
        parentList.forEach(e -> {
            List<ProductRsp> subList = all.stream().filter(o -> o.getParentUuid().equals(e.getUuid())).collect(toList());
            e.setSubList(subList);
            if(! CollectionUtils.isEmpty(subList)) getSubList(subList, all); }); }Copy the code