迭代自引用实体列表时出现问题(Spring Boot + Thymeleaf)
Problem in iterating list of self referencing entities (Spring Boot + Thymeleaf)
我正在开发一个电子商务应用程序,我有一个类别 class 和一个项目 class 等等。类别是自引用的,因为它也应该处理子类别。现在,我正在尝试制作一个遍历所有类别的 select 元素,但我的大脑就是想不出如何做到这一点。可能是我对类别的思考方式完全错误,整个逻辑需要重新评估..也欢迎在该级别发表评论!
Class 项目:
@Entity
@NoArgsConstructor
@Getter
@Setter
@ToString
public class Item implements Serializable, Comparable<Item> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private ItemType itemType;
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "category")
private Category category;
... Unrelated object properties etc.
}
Class 类别:
@Entity
@NoArgsConstructor
@Data
public class Category extends AbstractPersistable<Long> {
@NotNull
private String name;
@JsonBackReference
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "parentCategory")
private Category parentCategory;
@OneToMany(mappedBy = "parentCategory")
private List<Category> subCategories = new ArrayList<>();
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "category")
private List<Item> items = new ArrayList<>();
public Category(String name) {
this.name = name;
}
public Category(String name, Category parent) {
this.name = name;
this.parentCategory = parent;
}
}
添加到模型的类别列表:
model.addAttribute("categories", categoryRepository.findAll());
百里香叶:
<select class="form-control" id="category" name="category">
<option>All</option>
<div th:each="category : ${categories}">
<option class="optionGroup" th:text="${category.name}" th:value="${category.id}"></option>
<option class="optionChild" th:each="subCategory : ${category.subCategories}" th:text="${subCategory.name}" th:value="${subCategory.id}"></option>
</div>
</select>
显示为:
场外的想法是在父类别下显示子类别(饮料 > 酒精 > 啤酒等)
现在,我不确定如何考虑这个问题。也许修复在于 JPARepository 查询。也许我不应该使用 findAll() 而是一些自定义的东西。无论如何,当我想根据类别查找项目时,我必须处理这个问题:如何将子类别包含到查询结果中?
Ps。我没有使用 optgroup,因为我还希望父类别可以选择。
提前致谢!
最简单的解决方案(CategoryRepository
):
// finds only parent categories
List<Category> findByParentCategoryIsNull();
或使用“自定义命名”和 @Query
:
@Query("select c from Category c where c.parentCategory is null")
List<Category> findParents();
感谢 xerx593 的建议,从数据库中获取“主分类”作为起点,我最终得到了一个 thymeleaf 的解决方案,它并不漂亮并且仍然存在一些问题。但迭代至少以某种方式这样工作:
A solution as a question :)
我正在开发一个电子商务应用程序,我有一个类别 class 和一个项目 class 等等。类别是自引用的,因为它也应该处理子类别。现在,我正在尝试制作一个遍历所有类别的 select 元素,但我的大脑就是想不出如何做到这一点。可能是我对类别的思考方式完全错误,整个逻辑需要重新评估..也欢迎在该级别发表评论!
Class 项目:
@Entity
@NoArgsConstructor
@Getter
@Setter
@ToString
public class Item implements Serializable, Comparable<Item> {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private ItemType itemType;
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "category")
private Category category;
... Unrelated object properties etc.
}
Class 类别:
@Entity
@NoArgsConstructor
@Data
public class Category extends AbstractPersistable<Long> {
@NotNull
private String name;
@JsonBackReference
@ManyToOne(cascade = CascadeType.MERGE)
@JoinColumn(name = "parentCategory")
private Category parentCategory;
@OneToMany(mappedBy = "parentCategory")
private List<Category> subCategories = new ArrayList<>();
@LazyCollection(LazyCollectionOption.FALSE)
@OneToMany(mappedBy = "category")
private List<Item> items = new ArrayList<>();
public Category(String name) {
this.name = name;
}
public Category(String name, Category parent) {
this.name = name;
this.parentCategory = parent;
}
}
添加到模型的类别列表:
model.addAttribute("categories", categoryRepository.findAll());
百里香叶:
<select class="form-control" id="category" name="category">
<option>All</option>
<div th:each="category : ${categories}">
<option class="optionGroup" th:text="${category.name}" th:value="${category.id}"></option>
<option class="optionChild" th:each="subCategory : ${category.subCategories}" th:text="${subCategory.name}" th:value="${subCategory.id}"></option>
</div>
</select>
显示为:
场外的想法是在父类别下显示子类别(饮料 > 酒精 > 啤酒等) 现在,我不确定如何考虑这个问题。也许修复在于 JPARepository 查询。也许我不应该使用 findAll() 而是一些自定义的东西。无论如何,当我想根据类别查找项目时,我必须处理这个问题:如何将子类别包含到查询结果中?
Ps。我没有使用 optgroup,因为我还希望父类别可以选择。
提前致谢!
最简单的解决方案(CategoryRepository
):
// finds only parent categories
List<Category> findByParentCategoryIsNull();
或使用“自定义命名”和 @Query
:
@Query("select c from Category c where c.parentCategory is null")
List<Category> findParents();
感谢 xerx593 的建议,从数据库中获取“主分类”作为起点,我最终得到了一个 thymeleaf 的解决方案,它并不漂亮并且仍然存在一些问题。但迭代至少以某种方式这样工作: A solution as a question :)