JAPANESE 如何在没有额外列或额外映射表的情况下拥有主键外键关系

Posted

技术标签:

【中文标题】JAPANESE 如何在没有额外列或额外映射表的情况下拥有主键外键关系【英文标题】:JAP how to have primary key foreign key relation without having extra column or extra mapping table 【发布时间】:2016-05-23 14:15:03 【问题描述】:

从图片上看,是否可以将 QUALIFICATION_ID 作为 ID 的外键,而不需要额外的映射列或表?

TABLE --> TM_QUALIFICATIONS 是主表,ID 是自动生成的 UUID,名称是字符串值。值将在应用程序启动时插入到此表中。

TABLE --> TM_USER_QUALIFICATIONS,一个用户可以有多个资格。

那么如果没有任何其他额外的映射列或表,是否可以将 QUALIFICATION_ID 标记为外键?

另外,我如何结合 USER_ID 和 QUALIFICATION_ID 来为 TM_USER_QUALIFICATIONS 表创建复合主键?

提前致谢

【问题讨论】:

【参考方案1】:

我认为如果没有额外的列或额外的映射表,您就无法定义外键关系。

如果我理解正确,你可以做类似的事情

TM_QUALIFICATIONS

    @Entity
    @Table(name = "TM_QUALIFICATIONS")
    public class Qualifications 

        @Id
        @GeneratedValue(generator = "uuid")
        @GenericGenerator(name = "uuid", strategy = "uuid2")
        @Column(name = "ID")
        private String id;

        @Column(name = "NAME")
        private String name;

        public String getName() 
            return name;
        

        public void setName(String name) 
            this.name = name;
        

    

为了使 QUALIFICATION_ID 作为外键,你需要编写单独的 DDL 来添加约束。

@Repository
public interface UserQualificationsRepository extends CrudRepository<UserQualifications, String>

    @Modifying
    @Transactional
    @Query(value = "ALTER TABLE TM_USER_QUALIFICATIONS ADD FOREIGN KEY (QUALIFICATION_ID) REFERENCES TM_QUALIFICATIONS(ID)", nativeQuery = true)
    public void addForeignKeyConstraint();

TM_USER_QUALIFICATIONS

@Entity
@Table(name = "TM_USER_QUALIFICATIONS")
@IdClass(UserQualificationPK.class)
public class UserQualifications 

    @Id
    @Column(name = "USER_ID")
    private String userId;

    @Column(name = "LEVEL")
    private int level = 0;

    @Id
    @Column(name = "QUALIFICATION_ID")
    private String qualificationId;

    public String getUserId() 
        return userId;
    

    public void setUserId(String userId) 
        this.userId = userId;
    

    public int getLevel() 
        return level;
    

    public void setLevel(int level) 
        this.level = level;
    

最后对于复合主键使用@IdClass注解

public class UserQualificationPK implements Serializable 

    private String userId;

    private String qualificationId;

    public UserQualificationPK(String userId, String qualificationId) 
        this.userId = userId;
        this.qualificationId = qualificationId;
    

    public String getUserId() 
        return userId;
    

    public void setUserId(String userId) 
        this.userId = userId;
    

    public String getQualificationId() 
        return qualificationId;
    

    public void setQualificationId(String qualificationId) 
        this.qualificationId = qualificationId;
    

这样你就可以达到你的要求。 TM_QUALIFICATIONS 和 TM_USER_QUALIFICATIONS 之间没有关系,但是您通过本机 SQL 将 QUALIFICATION_ID 显式定义为外键。

【讨论】:

以上是关于JAPANESE 如何在没有额外列或额外映射表的情况下拥有主键外键关系的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core API - 如何在映射后将额外字段插入数据库

RestKit CoreData 0.20.3 - 映射完成后保存 MOC 之前的额外检查

如何向 Linq2SQL DBML 文件添加额外的程序集引用?

如何向 symfony 2 表单添加一些额外的数据

在 sqlalchemy 映射类构造函数中忽略额外关键字的选项?

Hibernate 注释用法