遞歸查詢子分類


遞歸查詢子分類

電商平台比如京東和淘寶中,商品一般分三級菜單。要想實現一個接口查詢一個商品的分類及其子分類信息,需要使用到遞歸查詢。

數據表中的記錄都是單條並且沒有層級的,要想描述各個記錄之間的層級父子關系,一般會設計一個 parentId字段。

CREATE TABLE `t_category`  (
 `cat_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '分類id',
 `name` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '分類名稱',
 `parent_cid` bigint(20) NULL DEFAULT NULL COMMENT '父分類id',
 `cat_level` int(11) NULL DEFAULT NULL COMMENT '層級',
 `show_status` tinyint(4) NULL DEFAULT NULL COMMENT '是否顯示[0-不顯示,1顯示]',
 `sort` int(11) NULL DEFAULT NULL COMMENT '排序',
 `icon` char(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '圖標地址',
 `product_unit` char(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '計量單位',
 `product_count` int(11) NULL DEFAULT NULL COMMENT '商品數量',
 PRIMARY KEY (`cat_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1433 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '商品三級分類' ROW_FORMAT = Dynamic;

數據:

下面簡述查詢所有商品分類及其子分類的接口。

實體類:CategoryEntity

import java.io.Serializable;
import java.util.Date;
import java.util.List;

import lombok.Data;
@Data
@TableName("t_category")
public class CategoryEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 分類id
	 */
	@TableId
	private Long catId;
	/**
	 * 分類名稱
	 */
	private String name;
	/**
	 * 父分類id
	 */
	private Long parentCid;
	/**
	 * 層級
	 */
	private Integer catLevel;
	/**
	 * 是否顯示[0-不顯示,1顯示]
	 */
	private Integer showStatus;
	/**
	 * 排序
	 */
	private Integer sort;
	/**
	 * 圖標地址
	 */
	private String icon;
	/**
	 * 計量單位
	 */
	private String productUnit;
	/**
	 * 商品數量
	 */
	private Integer productCount;

	@TableField(exist = false)
	private List<CategoryEntity> children;

}

為了表示子菜單,這里添加一個數據表中不存在的字段 children,並且使用注解標識。


接口:

/**
 * 查出所有分類以及子分類,以樹形結構組裝起來
 */
public List<CategoryEntity> listWithTree() {
  // 1. 查出所有分類
  List<CategoryEntity> entities = baseMapper.selectList(null);

  // 2. 組裝成父子的樹形結構
  // 2.1 找到所有的一級分類
  List<CategoryEntity> level1Menus = entities.stream().filter(categoryEntity ->
  		categoryEntity.getParentCid() == 0
  ).map(menu -> {
    // 2.2 設置子菜單
    menu.setChildren(getChildren(menu, entities));
    return menu;
    // 2.3 排序
  }).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
    .collect(Collectors.toList());
  return level1Menus;
}

/**
 * 遞歸查找所有菜單的子菜單
 */
private List<CategoryEntity> getChildren(CategoryEntity root, List<CategoryEntity> all) {
  List<CategoryEntity> children = all.stream().filter(categoryEntity ->
  		categoryEntity.getParentCid() == root.getCatId()
  ).map(categoryEntity -> {
    // 1. 找到子菜單
    categoryEntity.setChildren(getChildren(categoryEntity, all));
    return categoryEntity;
  }).sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort()))).collect(Collectors.toList());
  return children;
}

前端數據效果:

這個模型有遞歸查詢的接口中經常用到。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM