【问题标题】:How to sort the self-reference structure?如何对自引用结构进行排序?
【发布时间】:2020-12-08 13:25:25
【问题描述】:

在我的 Spring Boot 应用程序中,有一个具有 sefl-reference 的模型“Item”。我想实现按字段 sortOrder 排序,但我不明白如何为 CRUD 操作实现它。 例如,如何在将我的实体保存到存储库之前获取 sortOrder 的值,以及如何在更新实体后重新计算 sortOrder。任何帮助将不胜感激!谢谢!

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "item")
public class Item {

    @Id
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @SequenceGenerator(name = "itemSeq", sequenceName = "item_id_seq", allocationSize = 50)
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "itemSeq")
    private Long id;

    @NotBlank
    @Column(name = "name")
    private String name;

    @Column(name = "description")
    private String description;

    @Column(name = "sort_order")
    private String sortOrder;

    @Column(name = "is_active")
    private Boolean isActive;

    @ManyToOne
    @JoinColumn(name = "parent_id")
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    @JsonIgnoreProperties({"name", "description", "sortOrder", "isActive", "parent", "children"})
    private Item parent;

    @OneToMany(mappedBy = "parent", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @Where(clause = "is_active = true")
    @Fetch(FetchMode.SUBSELECT)
    @OrderBy("sort_order ASC")
    private List<Item> children = new ArrayList<>();
}

【问题讨论】:

    标签: java hibernate spring-data-jpa spring-data


    【解决方案1】:

    假设您要保存的新实体的 sort_order 为 x,

    首先,您必须递增所有其他具有 sort_order >= x 的列。最简单的方法是使用本机查询。

    @Modifying
    @Query("update item set sort_order = sort_order + 1 where sort_order >= ?1", nativeQuery = true)
    int incrementSortOrders(int currentSortOrder);
    

    在此之后,只需使用保存新实体即可

    repository.save(item)
    

    更新:

    如果 sort_order 的格式为 1-3-0、1-3-1、1-3-2、1-3-3 以表示递归顺序,那么这是一种可能的解决方案 -

    假设我们得到排序键为 1-3-1 的新实体,

    1. 我们仍然可以使用 > 运算符识别要递增的项目,因为它们在字典上会更大。
    2. 我们可以通过在代码中编写逻辑来计算当前节点序列的前缀为1-3-

    然后我们可以运行以下查询来每隔一行递增一次。

    @Modifying
    @Query("update item set sort_order = CONCAT(:prefix ,CONVERT(SUBSTRING_INDEX(sort_order, :prefix, -1), UNSIGNED INTEGER) + 1) where sort_order > :currentNodeOrder", nativeQuery = true)
    int incrementSortOrders(String prefix, String currentNodeOrder); //prefix is `1-3-` which was pre calculated and current node order is `1-3-1`
    

    【讨论】:

    • 感谢您的回答!也许您知道为 sefl-reference 案例实现 sortOrder 值的一些最佳实践?例如,我知道 UI 库使用 0-1-0 -> 0-1-1 之类的特定值来描述树状关系。我认为就我而言,我应该实现一些接近的东西。我无法想象如何去做以及在更改某些元素的订单后如何更新。
    • 我还是不太清楚你的问题。这些是我的疑惑。您是否会对所有元素的表格进行整体排序?当您获取要更新的实体时,您会根据您的排序在请求中获得哪些信息?
    • 从角度来看,我的服务将从客户端获取具有某种 sortOrder 值(如 0-2)的实体。尽管如此,如果我将在第二层拥有一个包含大量元素的结构,我应该将我的所有元素从之前的 0-2 更新到 0-99。我想使用最优化的方式。
    猜你喜欢
    • 2020-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2019-12-27
    • 2021-04-07
    • 1970-01-01
    相关资源
    最近更新 更多