当前位置: 首页 > 面试题库 >

如何在辅助表中的非主键列上联接表?

陆高峰
2023-03-14
问题内容

我遇到一种情况,我需要在ORM类层次结构中的对象上联接表,其中join列不是基类的主键。这是表格设计的示例:

CREATE TABLE APP.FOO
(
    FOO_ID INTEGER NOT NULL,
    TYPE_ID INTEGER NOT NULL,
    PRIMARY KEY( FOO_ID )
)

CREATE TABLE APP.BAR
(
    FOO_ID INTEGER NOT NULL,
    BAR_ID INTEGER NOT NULL,
    PRIMARY KEY( BAR_ID ),
    CONSTRAINT bar_fk FOREIGN KEY( FOO_ID ) REFERENCES APP.FOO( FOO_ID )
)

CREATE TABLE APP.BAR_NAMES
(
    BAR_ID INTEGER NOT NULL,
    BAR_NAME VARCHAR(128) NOT NULL,
    PRIMARY KEY( BAR_ID, BAR_NAME),
    CONSTRAINT bar_names_fk FOREIGN KEY( BAR_ID ) REFERENCES APP.BAR( BAR_ID )
)

这是映射(为简洁起见,省略了getter和setter方法

@Entity
@Table(name = "FOO")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "TYPE_ID", discriminatorType =    javax.persistence.DiscriminatorType.INTEGER)
public abstract class Foo {
    @Id
    @Column(name = "FOO_ID")
    private Long fooId;
}

@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo{
    @Column(table = "BAR", name = "BAR_ID")
    Long barId;
 }

BAR_NAMES鉴于其连接列不是FOO_ID,我如何添加映射BAR_ID

我尝试了以下方法:

@CollectionOfElements(fetch = FetchType.LAZY)
@Column(name = "BAR_NAME")
@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(table = "BAR", name = "BAR_ID", referencedColumnName="BAR_ID"))
List<String> names = new ArrayList<String>();

这将失败,因为用于检索Bar对象的SQL试图从FOO表中获取BAR_ID值。我也尝试过将JoinTable注释替换为

@JoinTable(name = "BAR_NAMES", joinColumns = @JoinColumn(name = "BAR_ID"))

这不会产生SQL错误,也不会检索任何数据,因为针对BAR_NAMES的查询使用FOO_ID作为联接值而不是BAR_ID。

为了进行测试,我使用以下命令填充了数据库

insert into FOO (FOO_ID, TYPE_ID) values (10, 1);
insert into BAR (FOO_ID, BAR_ID) values (10, 20);
insert into BAR_NAMES (BAR_ID, BAR_NAME) values (20, 'HELLO');

当获得ID为10的Foo对象时,许多似乎可行的解决方案将返回一个空集合(与包含1个名称的集合相对)


问题答案:

我能够找到解决方案。如果您像这样映射Bar类

@Entity
@DiscriminatorValue("1")
@SecondaryTable(name = "BAR", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID") })
public class Bar extends Foo {
    @OneToOne
    @JoinColumn(table = "BAR", name = "BAR_ID")
    MiniBar miniBar;
}

并添加以下类

@Entity
@SqlResultSetMapping(name = "compositekey", entities = @EntityResult(entityClass = MiniBar.class, fields = { @FieldResult(name = "miniBar", column = "BAR_ID"), }))
@NamedNativeQuery(name = "compositekey", query = "select BAR_ID from BAR", resultSetMapping = "compositekey")
@Table(name = "BAR")
public class MiniBar {
    @Id
    @Column(name = "BAR_ID")
    Long barId;
}

然后,您可以将想要的任何类型的映射添加到MiniBar类中,就像barId是主键一样,然后进一步使其在外部Bar类中可用。



 类似资料:
  • 我正在处理遗留系统,需要从数据库中读取一些信息。下面是表格关系 供应商(vendorid-pk,vendorEid,name) VendorContactBridge(bridgeid-pk,vendorEid,contactEid) 联系人(contactid-pk,contactEid,phone) vendorEid和contactEid不是表的主键,但用作联接表VendoContactBr

  • 我有两张这样结构的桌子。 表: 1) Obj表- 2) subobj表 我的场景是我有is_deleted列,在delete上我不想删除记录,而是想将is_deleted设置为true并更新所需的依赖项 详细场景: 1)考虑,用户正在从具有Id1.nowsubobj表中删除与obj_id1关联的行的obj表中删除一行,应该将is_deleted设置为true。 2) 子对象表包含自引用fk“父对象

  • 寻找解决以下问题的最佳方法 TBL1(本地SQL DB),其中ID=varchar 这将导致显示tbl1.id值,但所有tbl2.name值为空

  • 我试图用GlobalKTable连接KStream,连接不完全在键上。 我想通过empIdOverLoginUserId的值通过employeesDetails的键将empIdOverLoginUserId与employeesDetails连接

  • 错误结果为 “OneToOne关系的JPA问题:外键引用的列数错误。应为2” 如何为join测试表指定主键? 表A:列id与表B:列test_id映射

  • 问题内容: 我以前认为外键和辅助键是同一回事。 在谷歌搜索结果变得更加混乱之后,一些人认为它们是相同的,其他人则说,辅助键是一个不必唯一的索引,并且与主键相比,它可以更快地访问数据。 有人可以解释其中的区别吗? 还是确实是混合术语的情况? 每个数据库类型是否可能有所不同? 问题答案: Wiki / Foreign_key中的定义指出: 在关系数据库的上下文中,外键是一个表中的一个字段(或字段的集合