代码之家  ›  专栏  ›  技术社区  ›  suhair

如何在Hibernate中表示与同一表/实体的多对多关系?

  •  0
  • suhair  · 技术社区  · 17 年前

    有可能吗?我的意思是,多对多关系的两端可以指向同一个表吗?

    2 回复  |  直到 17 年前
        1
  •  1
  •   Jonathan Leffler    17 年前

    我不知道如果没有巨大的,可怕的冗余,你会怎么做。处理两个表之间多对多关系的标准方法是通过第三个表,该表包含两个主键值,一个用于第一个表,一个用于第二个表,在所有这些列的组合上具有唯一约束(读取“index”),可能在单独的主表上具有一个或两个重复(非唯一)索引。钥匙。概要:

    CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...);
    CREATE TABLE Table2 (pkcol2 ... PRIMARY KEY, ...);
    CREATE TABLE MtoM_Table1_Table2
    (
         pkcol1 ... REFERENCES Table1,
         pkcol2 ... REFERENCES Table2,
         PRIMARY KEY (pkcol1, pkcol2)
    );
    -- CREATE INDEX fk1_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol1);
    -- CREATE INDEX fk2_mtom_table1_table2 ON MtoM_Table1_Table2(pkcol2);
    

    如果DBMS是智能的,则可以跳过主键的前导列上的单独索引,因为在搜索仅前导值时也可以使用主键上的索引。

    假设表1和表2是同一个表(事实上,我们只有表1),正如问题中所述;这通常仍然需要mtom_table1_table1映射表-一个与主表分离的表。映射表必须为pk(主键)列具有单独的名称,但映射表中的两列(或两组列)都将引用表1中的pk列。

    CREATE TABLE Table1 (pkcol1 ... PRIMARY KEY, ...);
    CREATE TABLE MtoM_Table1_Table1
    (
         pkcol1 ... REFERENCES Table1(pkcol1),
         akcol1 ... REFERENCES Table1(pkcol1),
         PRIMARY KEY (pkcol1, akcol1)
    );
    -- CREATE INDEX fk1_mtom_table1_table1 ON MtoM_Table1_Table1(pkcol1);
    -- CREATE INDEX fk2_mtom_table1_table1 ON MtoM_Table1_Table1(akcol1);
    

    如果您也希望消除映射表,那么您必须在表1中有第二列来保存另一个pk值-称之为fkcol1(对于外键列)。这会让你左右为难:什么是主键?必须是pkcol1和fkcol1的组合。但是fkcol1应该引用另一行的主键——所以有一个矛盾。即使假设你成功地避免了这个问题(如何,确切地说?),若要在多对多关系的引用侧具有“多行”,则主表中必须有多行,除FKCL之外的所有列中的数据都相同,但这些行将引用表中的其他行(通常不止一行)。这是一个矛盾加上冗余的噩梦,再加上你丢失了简单的主键,再加上弄清楚到底发生了什么事情,这将是可怕的。

    CREATE TABLE Table1
    (
        pkcol1 ... /* PRIMARY KEY */,
        fkcol1 ... /* FOREIGN KEY REFERENCES Table1(pkcol1) */,
        ...
    );
    -- CREATE INDEX fk1_table1 ON Table1(pkcol1);
    -- CREATE INDEX fk2_table1 ON Table1(fkcol1);
    

    所以,我相信唯一理智的答案是“不——你不能在同一个表中表示多对多关系的两端;你必须使用一个映射表来保留系统中任何“正常”工作的机会。

        2
  •  0
  •   Uri    17 年前

    如果您使用的是Hibernate注释,那么有一个@ManyToMany,它不确定XML等价物。它应该出现在您的发行版的API文档中