0

比如说,我有两个聚合父和子。一个 Parent 可以有多个 Childs (Children)。一个孩子只能属于一个父母。

我需要跟踪子实体的排序顺序,以便当您获取父实体的子实体时,列表按该顺序排列。

显而易见的数据库模式如下:

在此处输入图像描述

然而,模型的一个不变量需要是这个顺序是明确定义的。因此,如果您在 Child 上有一个方法,Child.SetOrdinal(int) 说,那么这个不变量不受保护(没有什么能阻止您将两个 Childs 设置为序数 3)。我不想将它们全部整合到一个大集合中。

我看到的替代方案是如下数据库: 在此处输入图像描述

我已经引入了一个链接表来存储关系和顺序,这将在 Parent 聚合内,其中可以保护不变量。然而,这确实增加了数据库的复杂性。

还有另一种方法,还是第一个更简单的版本还不错?

4

1 回答 1

0

采用第一种方法时,您的模型可能如下所示(假设 Parent 和 Child 是 AggregateRoot s):

public Class Parent {
    private Long id;
}

public Class Child {
    private Long id;
    private Long parentId; // most orm need this field.
}

然后,您可以使用childRepository.findBy(parentId): List<Child>检索属于 Parent 的所有孩子,并使用parentRepository.findBy(child.getParentId()):Parent检索孩子的 Parent。但这不是你的情况,因为你说“但是,模型的一个不变量需要是这个顺序是明确定义的”。这导致了另一种方法: Parent 和 Child 作为 AggregateRoot 和 ValueObject 来保持关系:

public Class Parent {
    private Long id;
    private List<LineChild> children;
}

public class LineChild {
    private int ordinal;
    private Long childId;
}

public Class Child {
    private Long id;
}

但是在我的过期时间里,大多数 orm 不支持这个(而是使用第二个数据库模式)。一些“half orm 工具”可以提供帮助,例如 iBATIS。

<resultMap class="Parent">
    <property name="id" column="id" />
    <property name="children" column="id" select="findChilren"/>
</resultMap>

<select id="findChilren" parameterClass="long" resultMap="LineChild">
    select * from Child where parant_id = #parantId# order by ordinal
</select>

<resultMap id="LineChild" class="LineChild">
    <property name="ordinal" column="ordinal" />
    <property name="childId" column="id"/>
</resultMap>

但是你失去了一个 orm 框架的所有好处,比如动态更新等等。

或者,考虑最终的一致性?

最后但很困惑,为什么“一个孩子只能属于一个父母”?我有爸爸妈妈!:P

于 2013-09-13T09:38:53.903 回答