我有两个聚合父母和孩子,比方说。父母可以有很多孩子(孩子)。 一个孩子只能属于一个父母。
我需要跟踪子实体的排序顺序,以便当您获得父级的子实体时,列表按此顺序排列。
明显的数据库架构如下:
但是,模型的不变量需要是明确定义此顺序。 因此,如果你在Child上有一个方法,Child.SetOrdinal(int)说,那么这个不变量就不受保护了(没有什么可以阻止你将两个Childs设置为序数3)。 我不想将它们全部集中到一个大的聚合中。
我看到的替代方案是如下数据库:
我已经引入了一个链接表来存储关系和顺序,这将在Parent聚合中,其中可以保护不变量。但这确实增加了数据库的复杂性。
还有另一种方式,还是第一种更简单的版本还不错?
答案 0 :(得分:0)
采用第一种方法时,您的模型可能看起来像这样(假设父和子是AggregateRoot):
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>
检索属于父级的所有子级,并使用parentRepository.findBy(child.getParentId()):Parent
检索子级的父级。但这不是你的情况,因为你说“然而,模型的不变量需要是这个顺序是明确定义的”。这导致了另一种方法:Parent和Child as 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不支持这个(使用第二个db模式)。一些“半工具”可以提供帮助,比如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