Java 与 table 相关的实体建模
Java entity modeling with table that relates to several others
我对我的实体的建模方式有疑问。来吧,我在数据库中有一个 table 用于从我的系统保存文档,这个 table 有列 id,fk_id(元素外键),fk_table (实体名称)和 file_name(存储我的文件的名称).
我在这里发布我的问题之前做了很多研究,但我没有找到任何相关的东西,我的实体、用户、患者和医生会是什么?
数据库:
id
fk_id
fk_table
file_name
1
21
user
test1.jpg
2
32
doctor
test2.pdf
3
61
user
test10.pdf
4
100
patient
test5.jpg
Class:
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String LastName;
// What would a one-to-many relationship look like?
}
public class patient{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
// What would a one-to-many relationship look like?
}
您可以使用 @Where
。但请注意 @Where
是一个 Hibernate 注释。它不在 JPA 标准中。
例如在 User 实体中:(我假设您的 table 映射到名为 Document 的实体)
@Where( clause = "fk_table = 'user'")
@JoinColumn(name = "fk_id")
@OneToMany
private List<Document> documents = new ArrayList<>( );
以下仅基于标准 JPA 注释。这个想法是为文档 table 创建一个继承层次结构。基数是:
@Entity
@Table(name = "XX_DOCUMENT")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "fk_table")
public abstract class BaseDocument {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@Column(name = "file_name")
private String fileName;
}
这里我们定义所有扩展这个的实体都会去同一个table,用fk_table
列来区分。扩展它的实体定义如下:
@Entity
@DiscriminatorValue("doctor")
public class DoctorDocument extends BaseDocument {
@ManyToOne
@JoinColumn(name = "fk_id")
private Doctor doctor;
}
@Entity
@DiscriminatorValue("patient")
public class PatientDocument extends BaseDocument {
@ManyToOne
@JoinColumn(name = "fk_id")
private Patient patient;
}
// and so on
有趣的是,我们正在重用列 fk_id
以指向右侧 table。从一个小实验来看,Hibernate 似乎没有问题。为了安全起见,我建议您以另一种方式管理数据库创建。
Doctor
、Patient
等不需要有共同的基础class,例如:
@Entity
@Table(name = "XX_DOCTOR")
public class Doctor {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@OneToMany(mappedBy = "doctor")
private Collection<DoctorDocument> documents = new ArrayList<>();
// any doctor-specific fields
}
@Entity
@Table(name = "XX_PATIENT")
public class Patient {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@OneToMany(mappedBy = "patient")
private Collection<PatientDocument> documents = new ArrayList<>();
// any patient-specific fields
}
// and so on
您可以从相关集合中阅读(医生,患者,...)的文档。您甚至可以根据任何条件查询 BaseDocument
个实例。
您甚至可以继续使用 Java 代码来做更多有趣的事情。例如。定义接口 HasDocuments
:
public interface HasDocuments<D extends BaseDocument> {
Collection<D> getDocuments();
}
Doctor
, Patient
, ..., 实现了这个,所以他们都可以以同样的方式对待。
我对我的实体的建模方式有疑问。来吧,我在数据库中有一个 table 用于从我的系统保存文档,这个 table 有列 id,fk_id(元素外键),fk_table (实体名称)和 file_name(存储我的文件的名称).
我在这里发布我的问题之前做了很多研究,但我没有找到任何相关的东西,我的实体、用户、患者和医生会是什么?
数据库:
id | fk_id | fk_table | file_name |
---|---|---|---|
1 | 21 | user | test1.jpg |
2 | 32 | doctor | test2.pdf |
3 | 61 | user | test10.pdf |
4 | 100 | patient | test5.jpg |
Class:
public class User{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String LastName;
// What would a one-to-many relationship look like?
}
public class patient{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
// What would a one-to-many relationship look like?
}
您可以使用 @Where
。但请注意 @Where
是一个 Hibernate 注释。它不在 JPA 标准中。
例如在 User 实体中:(我假设您的 table 映射到名为 Document 的实体)
@Where( clause = "fk_table = 'user'")
@JoinColumn(name = "fk_id")
@OneToMany
private List<Document> documents = new ArrayList<>( );
以下仅基于标准 JPA 注释。这个想法是为文档 table 创建一个继承层次结构。基数是:
@Entity
@Table(name = "XX_DOCUMENT")
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "fk_table")
public abstract class BaseDocument {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@Column(name = "file_name")
private String fileName;
}
这里我们定义所有扩展这个的实体都会去同一个table,用fk_table
列来区分。扩展它的实体定义如下:
@Entity
@DiscriminatorValue("doctor")
public class DoctorDocument extends BaseDocument {
@ManyToOne
@JoinColumn(name = "fk_id")
private Doctor doctor;
}
@Entity
@DiscriminatorValue("patient")
public class PatientDocument extends BaseDocument {
@ManyToOne
@JoinColumn(name = "fk_id")
private Patient patient;
}
// and so on
有趣的是,我们正在重用列 fk_id
以指向右侧 table。从一个小实验来看,Hibernate 似乎没有问题。为了安全起见,我建议您以另一种方式管理数据库创建。
Doctor
、Patient
等不需要有共同的基础class,例如:
@Entity
@Table(name = "XX_DOCTOR")
public class Doctor {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@OneToMany(mappedBy = "doctor")
private Collection<DoctorDocument> documents = new ArrayList<>();
// any doctor-specific fields
}
@Entity
@Table(name = "XX_PATIENT")
public class Patient {
@Id
@GeneratedValue(strategy=SEQUENCE)
private Long id;
@OneToMany(mappedBy = "patient")
private Collection<PatientDocument> documents = new ArrayList<>();
// any patient-specific fields
}
// and so on
您可以从相关集合中阅读(医生,患者,...)的文档。您甚至可以根据任何条件查询 BaseDocument
个实例。
您甚至可以继续使用 Java 代码来做更多有趣的事情。例如。定义接口 HasDocuments
:
public interface HasDocuments<D extends BaseDocument> {
Collection<D> getDocuments();
}
Doctor
, Patient
, ..., 实现了这个,所以他们都可以以同样的方式对待。