我正在学习链接表。虽然我理解 OneToOne。Person 表已被截断以节省空间。很明显,一个名字不能明确地表示一个特定的人。
第一种选择是单向连接,一个人有一个 TIN,他只能有一个。每个 TIN 都分配给一个特定的人,他也可以只是一个人,但我们不需要在 TIN 数据库中存储有关其所有者的信息。
人.java:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "persons", schema = "date")
public class Person {
@Id
@GeneratedValue
private long id;
@Column
private String name;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "inn_id", unique = true)
private InnBase innBase;
}
InnBase.java
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "inn_base", schema = "date")
public class InnBase {
@Id
@GeneratedValue
private long id;
@Column(name = "inn_number")
private int innNumber;
}
liquibase 文件
<changeSet id="create_person" author="alex">
<createTable tableName="person" schemaName="date">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="name" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
<column name="id_inn" type="INT">
<constraints nullable="false" foreignKeyName="fk_inn" referencedTableSchemaName="date"
referencedTableName="types" referencedColumnNames="id"/>
</column>
</createTable>
</changeSet>
<changeSet id="create_inn" author="alex">
<createTable tableName="inn_base" schemaName="date">
<column name="id" type="BIGINT" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="inn_number" type="VARCHAR(255)">
<constraints nullable="false"/>
</column>
</createTable>
</changeSet>
第二种选择是双向通信。
一个人有一个 TIN,他只能有一个。每个 TIN 都绑定了一个特定的人,他也可以只是一个。但是我们需要能够通过 TIN 找到它的所有者。在这种情况下,您需要更改 InnBase 类。
人.java:
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class Person {
@Id
@GeneratedValue
private long id;
@Column
private String name;
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinColumn(name = "inn_id", unique = true)
private InnBase innBase;
}
InnBase.java
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table
public class InnBase {
@Id
@GeneratedValue
private long id;
@Column(name = "inn_number")
private int innNumber;
@OneToOne (optional=false, mappedBy="innBase", fetch = FetchType.LAZY)
private Person owner;
}
我对这个话题的理解程度如何?
并告诉我在第二种情况下我需要如何更改 inn_base 表的 liquibase 文件。
据我了解,第二种情况,需要创建第三张表进行通信:
id | person_id | inn_id
但是如何更改实体的代码呢?
通过休眠创建表。事实证明,对于第二个选项,表格的结构根本没有改变。
在第一种情况下,一切都是正确的,但是没有必要制作单独的FK,即
在 Person 实体中,因为我们不能为 Preson 拥有另一个 InnBase,所以我们可以通过 Person id 链接它们,即
代替
另外,如果 ddl 将形成框架,它将如何通过 Person id 而不是正确的 FK 绑定
你需要使用注释
}
如果ddl不是由框架形成,而是通过其他工具形成,例如:liquiBase,flyWay,或者你想通过手动编写请求来绑定FK,就足够了
在第二种情况下,你有一个双向关系,这里很重要的是要了解谁是父方,谁是子方,在你的情况下,父级将分别是 InnBase,Person,在这种情况下习惯于在父端写一个同步方法,例如:
这还不是全部,仍然存在细微差别,具体取决于您将使用哪些工具进行选择,以及与父端延迟加载相关的插入和细微差别,以及其他方面。Tables for OneToOne links 不需要,如果您使用 liquiBase 为第二个选项创建 ddl,它不会与第一个不同,主要是链接在子侧表的 changeSet 中,因为 FK 将站在孩子一边