【问题标题】:Designing JPA Entity for Database Table为数据库表设计 JPA 实体
【发布时间】:2015-05-08 04:59:30
【问题描述】:

我正在设计一个投票应用程序并设计了一个包含 2 个表的数据库 - 州和地区。 这两个表是 -

状态明细表

State_ID NUMBER(3)

State_name VARCHAR2(30)

主键(State_ID)

地区详情表

District_ID NUMBER(3)

State_ID NUMBER(3)

区名 VARCHAR2(30)

PIN_Code NUMBER(6)

主键(区 ID)

唯一(州 ID,区名)

外键(State_ID)

由于两个州可以有一个同名的区,我正在考虑将州 ID 和区名称的组合作为唯一的组合。

现在我必须为这两个表设计 JPA 实体,但我无法设计,因为在数据库设计中,District 表中有 State ID 作为外键,但是在设计具有 State 的实体时District 内的对象听起来毫无意义,因为如果我在脑海中保留 HAS-A 关系,那么 District 中就没有 State州 HAS-A 区列表。这不符合上面的数据库设计。

有人可以帮助我为此设计 JPA 实体吗?请建议数据库设计是否也需要修改。 谢谢。

【问题讨论】:

标签: mysql database hibernate jpa entity


【解决方案1】:

基于Rick's proposal 的示例 JPA 方法:

@Entity
@Table(name = "States")
public class State {
    @Id
    @Column(nullable = false, columnDefinition = "CHAR(2) CHARACTER SET ascii")
    private String code;

    @Column(nullable = false, length = 30)
    private String name;

    @OneToMany(mappedBy = "state")
    private Collection<District> districts;

    public State() { }

    // getters, setters, etc.
}
@Entity
@Table(name = "Districts", uniqueConstraints = { 
    @UniqueConstraint(columnNames = { "state_code", "name" })
})
public class District {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(nullable = false, columnDefinition = "SMALLINT UNSIGNED")
    private short id;

    @Column(name = "state_code", nullable = false, 
            columnDefinition = "CHAR(2) CHARACTER SET ascii")
    private String code;

    @Column(length = 30)
    private String name;

    @ManyToOne
    @JoinColumn(name = "state_id")
    private State state;

    public District() { }

    // getters, setters, etc.
}

注意:由于使用了columnDefinition 属性,上述实体不能跨数据库移植。

【讨论】:

  • 感谢您的回答
【解决方案2】:
CREATE TABLE States (
    code CHAR(2) NOT NULL CHARACTER SET ascii,
    name VARCHAR(30) NOT NULL,
    PRIMARY KEY(code)
);
CREATE TABLE Districts
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    state_code CHAR(2) NOT NULL CHARACTER SET ascii,
    ...
    PRIMARY KEY(id),
    UNIQUE (state_code, name)
);

注意事项:
* 如果您在谈论美国,也可以使用标准州代码(AK、AL、...)。
* 可能States 的唯一目的是拼出名字。
* 如果您的表默认为 utf8,我对 ascii 很明确。
* MySQL 使用 VARCHAR,而不是 VARHAR2。
* 你可以去掉Districts.id,只剩下PRIMARY KEY(state_code, name),但我猜你还有一堆其他的表需要加入这个表,还有一个2字节的id会比笨重的替代品更好。

【讨论】:

  • 感谢@Rick 向我提出改进数据库设计的建议。但我真正的问题是如何将这些表计算为 JPA 实体?在数据库设计中,地区表中有一个州代码。但是,如果我将相同的设计视为一个对象,一个州 HAS-A 区,但该区中没有州。如果我的问题不清楚,我很抱歉。
  • 你说的是“Java Persistence API”吗?我对此一无所知。我假设每个“州”中有很多“区”,并且没有一个区是部分位于两个州中的。这在不同的圈子中称为多对一 (N:1) 关系。 (许多区到一个州)。这就是我编码的。我同意“地区”和“州”是“实体”。 N:1 不需要额外的表,只需要一列。多对多 (M:N) 确实需要一个额外的表。
  • 好的@Rick。感谢您的数据库创意。
猜你喜欢
  • 2014-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-19
  • 2011-02-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多