如何为2D数组执行Hibernate ORM映射

时间:2016-12-27 14:04:37

标签: java hibernate orm guava

我是ORM的新手并且遇到了以下问题(在此处进行了简化):

我正在与竞争对手和学科建立锦标赛。两者都有自己的实体类。竞争对手恰好在每个学科中竞争一次,并获得分数。只要竞争对手还没有参加某个特定的比赛,就没有得分。

数据模型:

简单的数据库设计将是一个得分表,其中包含竞争对手表和纪律表的外键。也就是说,我会设置两个一对多的关系,加上外键的完整性约束 - 只要有分数引用任何一个,我就不能删除竞争对手或学科。

但是如何将这个2D数组(竞争对手/学科)映射到我的课程?我正在使用Java和Hibernate。 我目前的解决方案是将一组分数放入竞争者实体类中,对于Disciplines类也是如此。这为两个实体类中的每一个创建了与连接表的双向关系。这是推荐的映射方式吗?

它确实从每个域类的透视图映射关系,但它错过了2D数组结构。我想输出整个数组 - 例如在UI上 - 用于竞争对手的行,用于学科的列以及相应表格单元格中的分数。如刚刚描述的那样从实体类构建这样的输出是繁琐的并且需要(a)遍历竞争者集合然后(b)查找相应的学科 - 或者反过来。

理想情况下,我希望有一个带有两个键的哈希映射,如Guava Table或嵌套的哈希映射。我想这种高级集合没有原生的Hibernate映射。但也许最好的做法是如何使用自定义查询来实现它?

1 个答案:

答案 0 :(得分:0)

  

但是如何将这个2D数组(竞争对手/学科)映射到我的课程?我正在使用Java和Hibernate。我目前的解决方案是将一组分数放入竞争者实体类中,对于Disciplines类也是如此。这为两个实体类中的每一个创建了与连接表的双向关系。这是推荐的映射方式吗?

IIRC,隐式联接表不允许添加分数。即使它确实如此,我也不喜欢它,因为分数实际上是主要信息。所以我要去一个明确的表格。

class Score {
    @ManyToOne(optional=false)
    Competitor competitor;
    @ManyToOne(optional=false)
    Discipline discipline;
}

这应该提供您需要的一切。您可能还需要课程Set<Score>中的Map<Discipline, Score>甚至Competitor(反之亦然),但您可能不需要它。映射可能会使用@ManyToMany(mappedBy="competitor")@MapKey ...我没有使用它很长时间,因为我发现我并不真的需要它。

  

理想情况下,我希望有一个带有两个键的哈希映射,例如Guava Table或嵌套的哈希映射。

使用默认@ManyToOne(fetch=EAGER),使用JOIN自动获取所需的竞争对手和规则。我担心,你可以获得List,但迭代一次并填充番石榴Table是微不足道的:

list.stream()
.forEach(score -> table.put(score.competitor, score.discipline, score));

不要忘记实体是可变的,但在用作密钥时不得变异。显然,您应该只获取所需的实体,而不是过滤Table。但是,一旦拥有Table,您就可以随意使用其所有操作; Hibernate不再对你有所帮助,但是你不需要它(而且你不想再次使用DB)。