实体类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@TableName("t_article")
public class Article {
    private Long id;
    private String title;
    private String content;
    private Long parentId;
}

DTO类

1
2
3
4
5
6
7
@Data
public class ArticleDTO {
    private Long id;
    private String title;
    private String content;
    private List<ArticleDTO> children;//这是重点
}

Service类

1
2
3
public interface ArticleService {
    List<ArticleDTO> getArticleList();
}

ServiceImpl类

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Override
    public List<ArticleDTO> getArticleList() {
        // 查询所有文章
        List<Article> articles = ArticleRepository.searchQuery();
        Map<String, ArticleResDto> articleMap = new HashMap<>();
        List<ArticleResDto> rootArticles = new ArrayList<>();
        
        // 遍历所有文章,将其转换为ArticleResDto对象,并存储在articleMap中
        // 这一步很重要,否则下一步for循环可能无法找到父节点导致数据丢失
        for (Article article : articles) {
            ArticleResDto articleResDto = new ArticleResDto();
            //将文章属性复制到文章DTO对象中对应属性中(两边属性字段必须相同,不相同的可以单独通过set方法赋值)
            BeanUtils.copyProperties(article, articleResDto);
            articleMap.put(article.getCode(), articleResDto);
        }
        // 遍历所有文章,将其转换为ArticleResDto对象,并存储在rootArticles中
        for (Article article : articles) {
            // 从articleMap中获取对应的ArticleResDto对象
            ArticleResDto articleResDto = articleMap.get(article.getCode());
            // 如果该文章的parent为0,则将其作为根节点存储在rootArticles中
            if (article.getParent().equals("0")) {
                rootArticles.add(articleResDto);
            } else {
                // 如果该文章的parent不为0,则将其作为子节点存储在对应的父节点的children中
                ArticleResDto parentarticle = articleMap.get(article.getParent());
                if (parentarticle != null) {
                    // 如果父节点的children为null,则创建一个新的List对象
                    if (parentarticle.getChildren() == null) {
                        parentarticle.setChildren(new ArrayList<>());
                    }
                    parentarticle.getChildren().add(articleResDto);
                }
            }
        }
        return rootArticles;
    }
    // 返回顶级文章列表
    /**
     * 输出结果:
     * [
     *     {
     *         "id": 1,
     *         "title": "文章1",
     *         "content": "文章1的内容",
     *         "children": [
     *             {
     *                 "id": 2,
     *                 "title": "文章2",
     *                 "content": "文章2的内容",
     *                 "children": []
     *             }
     *         ]
     *     }
     * ]
     */
    return articleDTOs;
}

BeanUtils.copyProperties(article, articleDTO);将文章属性复制到文章DTO对象中对应属性中

  • BeanUtils.copyProperties 不会复制静态字段、final 字段以及没有 getter/setter 方法的字段。
  • 如果需要排除某些属性不进行复制,可以使用 BeanUtils.copyProperties 的第三个参数指定要忽略的属性名数组。

当然也可以使用geter/setter方法进行复制,比如:articleDTO.setName(article.getName());逐个复制每个属性