如何创建一个外键和一个主键的组合键 Spring Data JPA

How to create a composite key of one foreign key and one primary key Spring Data JPA

我正在使用 Spring Boot 构建一个 API。这是惩罚系统的API。在数据库中有两个用于规则的 table,它们是规则 table 和社区 table。

规则 ID 是整数,社区 ID 是来自社区 table 的外键。一个社区应该有 0 条、1 条或许多条规则,而一条规则恰好是由一个社区制定的。

这是我希望在我的 Spring 启动应用程序中复制的行为。

到目前为止我有以下代码:

Community.java

@Entity // Maps to database
public class Community {
    @Id
    @Column(name = "id", length = 16, unique = true, nullable = false)
    private UUID id;

    @Column(name = "username", length = 20, nullable = false)
    private String name;

Rule.java

@Entity // Maps to database
public class Rule {

    @EmbeddedId
    private RuleId ruleId;

    @Column(name = "description", length = 50, nullable = false)
    private String description;

RuleId.java

@Embeddable
public class RuleId implements Serializable {

    private UUID communityId;
    private Integer ruleId;

    public RuleId(UUID communityId, Integer ruleId) {
        this.communityId = communityId;
        this.ruleId = ruleId;
    }

我已经阅读了堆栈上的一些线程,这是我从中获得嵌入式想法的地方,但我仍然对如何让它与我的场景一起工作感到困惑。非常感谢任何帮助来消除这种困惑。

干杯:)

您可以使用注释 @JoinColumn(...) 并指定关系,在您的情况下:@OneToOne(...)

然后你可以简单地定义你的 Rule 实体只有 Long idint id 和作为:

@Entity
public class Rule {
    
    @Id // map as id field
    @GeneratedValue(strategy = GenerationType.AUTO) // Auto generate id when update db
    @Column(name = "Rule_Id") // map the column field
    private Long ruleId;
    
    // Simply add annotation to map foreign key
    @OneToOne
    @JoinColumn(name = "community_id_fk", referencedColumnName = "community_id")
    private Community community;    

    // more field ...
    @Column(name = "description", length = 50, nullable = false)
    private String description;
}

更多攻略请看https://www.baeldung.com/jpa-one-to-one

我通过 Zukaru 的回答中的一对一关系解决了这个问题。

我想要的是由community_idrule_id组成的组合键。 Community Id 是 Communities table.

上主键的外键

为了实现这个,我有 2 个 类。 RuleRulePrimaryData.

Rule.java

@Entity // Maps to database
@Table(name = "rules")
@Data
@NoArgsConstructor
public class Rule {

    @EmbeddedId
    private RulePrimaryData id;

    @OneToOne
    @JoinColumn(name = "community_id_fk", referencedColumnName = "community_id", insertable = false, updatable = false)
    private Community communities;

    @Column(name = "description", length = 50, nullable = false)
    private String description;

    public Rule(RulePrimaryData ruleId, String description) {
        this.id = ruleId;
        this.description = description;
    }
}

嵌入的 Id 用于制作包含 UUID 和 Integer 的复合键。

RulePrimaryData.java

@Embeddable
@NoArgsConstructor
@Data //Getters, setters, constructors
public class RulePrimaryData implements Serializable {

    @Column(name = "community_id_fk", nullable = false)
    private UUID communityId;

    @Column(name = "rule_id", nullable = false)
    private Integer ruleId;

    public RulePrimaryData(UUID communityId, int ruleId) {
        this.communityId = communityId;
        this.ruleId = ruleId;
    }
}

最后,我最初认为是多对一的关系是一对一的关系。在定义中,我将 EmbeddedId 的 community_id_fk 列加入到社区 table 中的 community_id 列。