Java 实现目录层级树

需求:

扁平化的数据库存储 转换成有层级的树。放一张图,更容易理解

 

  • controller
@RestController
@RequestMapping("/catalogue")
public class CatalogueController {

    @Autowired
    CatalogueService catalogueService;

    @PostMapping("/getStudentsInfo")
    public RestResponse<Object> getStudentsInfo(@RequestBody StudentRequest studentRequest){
        List<CatalogueDTO> studentDTOList = catalogueService.getCatalogueTree();
        return RestResponse.ok(studentDTOList);
    }
}
  • Services接口 && Services实现类
public interface CatalogueService {
    List<CatalogueDTO> getCatalogueTree();
}
@Service
public class CatalogueServiceImpl implements CatalogueService {
    @Autowired
    CatalogueMapepr catalogueMapepr;
    @Override
    public List<CatalogueDTO> getCatalogueTree() {
        List<CatalogueDO> catalogueDOList = catalogueMapepr.getCatalogueTree();

        // 此处是使用 mapstruct 的方式进行对象的copy 类似与 BeanUtils.copyProperties();
        List<CatalogueDTO> catalogueDtos= StudentConverter.INSTANCE.doToDto(catalogueDOList);

        // 获取顶层目录
        List<CatalogueDTO> topCatalogue = catalogueDtos.stream().filter(item -> item.getParentId() == null).collect(Collectors.toList());

        // 获取非顶层目录通过目录parentId做分组
        Map<Long, List<CatalogueDTO>> catalogueMap = catalogueDtos.stream()
                .filter(e -> e.getParentId() != null)
                .collect(Collectors.groupingBy(CatalogueDTO::getParentId));

        setChildren(topCatalogue,catalogueMap);
        return topCatalogue;
    }

    /**
     * 这种查询目录两个关键地方:递归 && 设置子集  从两个角度思考问题
     * 类比mybatis的嵌套子查询 孩子
     */

    public void setChildren(List<CatalogueDTO> catalogueDTO, Map<Long, List<CatalogueDTO>> catalogueMap) {
        for (CatalogueDTO dto : catalogueDTO) {
            List<CatalogueDTO> childrenDtos = catalogueMap.getOrDefault(dto.getCatalogueId(),Lists.newArrayList());
            dto.setChildrenDTO(childrenDtos);
            setChildren(childrenDtos,catalogueMap);
        }
    }
}
  • Mapper接口
public interface CatalogueMapepr {
    /**
     * 查询所有的目录信息
     *
     * @return CatalogueDO
     */
    List<CatalogueDO> getCatalogueTree();
}
  • xml:sql
<resultMap id="catalogueResultMap" type="it.hww.entity.CatalogueDO" autoMapping="true">
</resultMap>
<select id="getCatalogueTree" resultMap="catalogueResultMap">
select * from meta_catalogue
</select>
  • 数据表
CREATE TABLE `meta_catalogue` (
  `catalogue_id` bigint(20) NOT NULL,
  `catalogue_code` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '目录编码/英文名',
  `catalogue_name` varchar(32) COLLATE utf8_bin DEFAULT NULL COMMENT '目录名称',
  `catalogue_status` varchar(2) COLLATE utf8_bin DEFAULT NULL COMMENT '状态 0:不可用、1:可用 ',
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父id',
  `sort` int(32) DEFAULT NULL COMMENT '序号',
  `id_path` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT 'id路径',
  `name_path` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '名称路径',
  `create_by` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '创建人',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(32) CHARACTER SET utf8 DEFAULT NULL COMMENT '更新人',
  `update_time` datetime DEFAULT NULL COMMENT '更新时间',
  `is_active` tinyint(1) DEFAULT NULL COMMENT '是否有效',
  PRIMARY KEY (`catalogue_id`) USING BTREE,
  UNIQUE KEY ```catalogue_id``` (`catalogue_id`) USING BTREE,
  KEY ```parent_id``` (`parent_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin ROW_FORMAT=DYNAMIC COMMENT='目录管理主表';
  • 数据对象
@Data
public class CatalogueDO {
    private Long catalogueId;
    private String catalogueCode;
    private String catalogueName;
    private Long parentId;
    private String idPath;
    private String namePath;
}
@Data
public class CatalogueDTO{

    private Long catalogueId;
    private String catalogueCode;
    private String catalogueName;
    private Long parentId;
    private String idPath;
    private String namePath;

    private List<CatalogueDTO> childrenDTO;

}
  • 此接口的作用就是把StudentDO转换成StudentDTO
@Mapper
public interface StudentConverter {
    StudentConverter INSTANCE = Mappers.getMapper(StudentConverter.class);

    /**
     * 实体之间转换
      * @param studentDO
     * @return StudentDTO
     */
    StudentDTO do2dto(StudentDO studentDO);

    /**
     * catalogueDOList--> CatalogueDTOList
     *
     * @param catalogueDOList catalogueDOList
     * @return CatalogueDTOList
     */
    List<CatalogueDTO> doToDto(List<CatalogueDO> catalogueDOList);

    CatalogueDTO doToDtoOne(CatalogueDO catalogueDO);
}

 

posted @ 2023-07-16 01:02  北冥_之鱼  阅读(338)  评论(0)    收藏  举报