【问题标题】:JPA/Hibernate Initialize object after a many-to-many join with another joinJPA/Hibernate 在与另一个连接进行多对多连接后初始化对象
【发布时间】:2018-03-08 15:20:31
【问题描述】:

抱歉标题措辞不佳,但我不知道如何实际表达它。

我目前有 3 个表格(我不确定如何在 SO 上格式化表格):

FOO
---------
ID
NAME
^^^^^^^^^
BAR
---------
ID
NAME
^^^^^^^^^
FOO_BAR
---------
ID
ID_FOO
ID_BAR
SOME_STRING

我目前正在做的是根据 FOO_BAR 表中的 ID_FOO 和 ID_BAR 加入 FOO 和 BAR,这是可行的。我在每个 Foo 对象中得到了一个不错的 List。

我现在尝试做的(至少了解如何做)是在每个 Bar 对象中填充 FOO_BAR.SOME_STRING 列的列表。举个例子:

FOO_BAR 包含:

ID_FOO | ID_BAR | SOME_STRING
1      | 1      | a
1      | 1      | b
1      | 2      | a
2      | 1      | c

我想在我的 Foo 对象中得到以下结果:

myFoo 包含两 (2) 个 ID 为 1 和 2 的 Bar 对象的列表。每个 Bar 对象都有一个字符串列表(在这种情况下),使用 FOO_BAR.SOME_STRING 值初始化。所以 barList[0] 将是 {"a", "b"} 的列表,而 barList[1] 将是字符串 "a" 的列表。

有什么方法可以以简单(-ish)的方式做到这一点?再次抱歉,这个奇怪的标题。

编辑:我在 FOO_BAR 表中添加了一个额外的条目以显示以下情况。 foo(1) 将有 2 个 Bar 对象,第一个 bar(1) 在其列表中有 2 个字符串。然而,对象 foo(2) 的列表中也有 bar(1),但 bar(1) 的列表中只有字符串“c”。

【问题讨论】:

    标签: mysql sql hibernate spring-data-jpa many-to-many


    【解决方案1】:

    根据您的问题,您的FOO_BAR 表不一定是这种结构。如果我们在 JPA 中对此进行建模,您实际上拥有:

    @Entity
    @Table(name = "FOO")
    public class Foo {
      // only including attributes that are of interest here, others omitted
      @ManyToMany(mappedBy = "foo")
      List<Bar> barList;
    }
    
    @Entity
    @Table(name = "BAR")
    public class Bar {
      // only including attributes that are of interest here, others omitted
      @ManyToMany
      private List<Foo> foo;
      @ElementCollection
      @CollectionTable(name = "FOO_BAR_STRINGS")
      private Set<FooString> someStrings;
    }
    
    @Embeddable 
    public class FooString {
      @ManyToOne
      private Foo foo;
      private String stringValue;
    }
    

    这将导致一个架构包含名为 FOOBARFOO_BARFOO_BAR_STRINGS 的表。

    FOOBAR 表将仅包含您作为其各自实体的一部分存储的基本属性。

    FOO_BAR 表将为FooBar 之间的@ManyToMany 关联维护一个交叉引用,类似于:

     +--------+---------
     | foo_id | bar_id |
     +--------+--------+
     |      1 | 1      |
     |      1 | 2      |
     +--------+--------+
    

    最后,将有一个FOO_BAR_STRINGS 集合表,该表将包含三列,关联Foo 的标识符和与拥有Bar 对象关联的stringValue。所有 3 个值的组合由称为 FooString 的可嵌入组件表示。

    这是一个视觉示例:

     +--------+--------+-------------+
     | bar_id | foo_id | stringValue |
     +--------+--------+-------------+
     |      1 |      1 | a           |
     |      1 |      1 | b           |
     |      2 |      1 | a           |
     |      1 |      2 | c           |
     +--------+--------+-------------+
    

    这为您提供了基于映射的完全标准化的数据视图。

    FooString的实现方式有多种,其表结构可以实现;这只是一种方式。另一种方法是在Foo 对象上应用元素集合并将FooString 更改为BarString,其中它包含对特定Bar 的引用。

    【讨论】:

    • 我现在添加了一个额外的示例。第三个表的 pk 应该是 foo_id 和 bar_id 对,因为您可以让 foo(1) 包含 bar(1) 和两个字符串的列表,但 bar(1) 也可以是 foo(2) 的一部分, 但只有一个字符串(可能与前两个不同)。使用连接进行设计是否太奇怪了?也许我应该只将列表作为逗号分隔的字符串,并且只有一个字段,然后我将在代码中将其转换为列表?
    • 如果您需要 FooBar 与给定字符串相关联,您可以随时更改元素集合以保存映射 FooBar 的嵌入对象,和字符串值作为条目。我将用它来更新我的示例。
    猜你喜欢
    • 1970-01-01
    • 2021-08-23
    • 2022-06-15
    • 2020-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-13
    • 1970-01-01
    相关资源
    最近更新 更多