【问题标题】:Spring boot + (JPA) - Category hierarchy - recursively traverseSpring boot + (JPA) - 类别层次结构 - 递归遍历
【发布时间】:2017-10-03 21:45:47
【问题描述】:

我有目录实体 -

public class Category {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column
private String categoryName;

@ManyToOne
@JoinColumn(name = "parent_id")
private Category parent;

@OneToMany(mappedBy = "parent", cascade = CascadeType.REMOVE, orphanRemoval = true)
private List<Category> children = new ArrayList<Category>();

@ManyToMany(mappedBy = "categories")
private Set<Product> 

以及表中的记录:

id,  category_name,   parent_id
'1', 'HOME',            NULL
'2', 'Category 1',       '1'
'3', 'Category 2',       '1'
'4', 'Sub-Category 1',   '2'
'5', 'Sub-Category 1 2', '2'

以及控制器中的一些方法(在我的情况下,但问题是原则)

List<Category> categoryList = categoryRepository.findAll();

    for (Category cat : cateList) {
        recursiveTree(cat);
    }



public void recursiveTree(Category cat) {
        System.out.println(cat.getCategoryName());
        if (cat.getChildren().size() > 0) {
            for (Category c : cat.getChildren()) {
                recursiveTree(c);
            }
        }
    }

当我运行它时,在控制台中我得到 -

HOME
Category 1
Sub-Category 1
Sub-Category 1 2
Category 2
Category 1
Sub-Category 1
Sub-Category 1 2
Category 2
Sub-Category 1
Sub-Category 1 2

如何修改递归,以便获得类别和子类别的正确顺序?我不知道为什么我会得到一些重复的数据

【问题讨论】:

  • 因为getChildren() 不起作用
  • 什么意思?你能帮我吗?
  • 我想,但我不知道怎么做。

标签: java spring jpa recursion


【解决方案1】:

您获得了重复的数据,因为您使用List&lt;Category&gt; categoryList = categoryRepository.findAll();从数据库中获取所有类别

此列表包含 HOME、Category 1、Category 2、...

由于您在主循环中调用此列表中的每个项目 recursiveTree 方法,您将为 HOME 打印树(因此将打印其所有子项),您还将为类别 1 调用 recursiveTree,再次打印该类别及其子类别,依此类推。

如果您希望每个类别只打印一次,请仅查找根类别(HOME 以及您可能拥有的任何其他没有父类别的类别)并为这些类别致电 recursiveTree。例如:

List<Category> rootCategoryList = categoryRepository.findByParentIsNull();
for (Category cat : rootCategoryList) {
    recursiveTree(cat);
}

【讨论】:

  • 你是天才!!我仍然无法理解它是如何工作的.. :) 再解释一下?我如何只获得具有 null 的父母,同时获得子目录(父目录没有 null 值)。你有一些教程如何在百里香视图中实现这个:)
  • 嗯,当在您的recursiveTree 方法中调用cat.getChildren() 时,将从数据库中检索孩子,以便将它们返回。请注意,如果您想在 thymeleaf 中做类似的事情,您应该首先遍历您的类别(即:调用类似于 recursiveTree 但不打印的方法),因为默认情况下,您不再可以使用数据库连接在视图渲染期间。要在 thymeleaf 中渲染,您可以使用片段 - 参见例如 this SO question
【解决方案2】:

为了在 thymeleaf 中显示类别树,这段代码完美运行

<div th:fragment="submenu">
        <ul>
            <li th:each="cat : ${categories}">
            <span th:text="${cat.categoryName}"></span>
                <div th:with="categories = ${cat.children}" th:include="admin/fragments/info :: submenu"></div>
            </li>
        </ul>
    </div>

【讨论】:

    猜你喜欢
    • 2019-06-08
    • 2014-12-07
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 2017-02-04
    相关资源
    最近更新 更多