【发布时间】:2017-01-31 21:25:36
【问题描述】:
假设我有一个 MySQL 数据库,其中包含两个表 patient 和 medicine。我在下面显示了他们的列。
患者
idPatient (int) (primary key)
first_name (varchar)
last_name (varchar)
医药
idMedicine (int) (primary key)
idPatient (int) (foreign key)
drug_name (varchar)
请注意Medicine 表确实有Patient 表的外键。
现在,如果我使用纯 JDBC,我将执行以下操作来为 Medicine 和 Patient 表创建一个 bean
PatientBean类
public class PatientBean
{
private int idPatient;
private String first_name;
private String last_name;
public void setIdPatient(int idPatient)
{
this.idPatient = idPatient;
}
public int getIdPatient()
{
return idPatient;
}
public void setFirstName(String first_name)
{
this.first_name = first_name;
}
public String getFirstName()
{
return first_name;
}
public void setLastName(String last_name)
{
this.last_name = last_name;
}
public String getLastName()
{
return last_name;
}
}
`MedicineBean` class
public class MedicineBean
{
private int idMedicine;
private int idPatient;
private String drug_name;
public void setIdMedicine(int idMedicine)
{
this.idMedicine = idMedicine;
}
public int getIdMedicine()
{
return idMedicine;
}
public void setIdPatient(int idPatient)
{
this.idPatient = idPatient;
}
public int getIdPatient()
{
return idPatient;
}
public void setDrugName(String drug_name)
{
this.drug_name = drug_name;
}
public String getDrugName()
{
return drug_name;
}
}
但是,如果我使用 NetBeans 之类的工具对我的数据库进行反向工程以实现休眠,该工具将为休眠生成 POJO 文件、映射等,我可以期待如下所示。
PatientBean类
public class PatientBean
{
private int idPatient;
private String first_name;
private String last_name;
private MedicineBean medicineBean;
public void setIdPatient(int idPatient)
{
this.idPatient = idPatient;
}
public int getIdPatient()
{
return idPatient;
}
public void setFirstName(String first_name)
{
this.first_name = first_name;
}
public String getFirstName()
{
return first_name;
}
public void setLastName(String last_name)
{
this.last_name = last_name;
}
public String getLastName()
{
return last_name;
}
public void setMedicineBean(String medicineBean)
{
this.medicineBean = medicineBean;
}
public String getMedicineBean()
{
return medicineBean;
}
}
MedicineBean类
public class MedicineBean
{
private int idMedicine;
private int idPatient;
private String drug_name;
private Set<PatientBean> patients = new HashSet<PatientBean>(0);
public void setIdMedicine(int idMedicine)
{
this.idMedicine = idMedicine;
}
public int getIdMedicine()
{
return idMedicine;
}
public void setIdPatient(int idPatient)
{
this.idPatient = idPatient;
}
public int getIdPatient()
{
return idPatient;
}
public void setDrugName(String drug_name)
{
this.drug_name = drug_name;
}
public String getDrugName()
{
return drug_name;
}
public void setPatients(Set<PatientBean>patients)
{
this.patients = patients;
}
public Set<PatientBean> getPatients()
{
return patients;
}
}
不仅如此,Hibernate 还会在 xml 文件中映射关系类型(一对一、一对多、多对一)。但是在 JDBC 中我们根本不关心它们,它们只是以相同方式处理的外键。
所以我的问题是,为什么会有这种差异?我相信 Hibernate 所做的大部分操作都是无用的,只是使用 CPU。例如,当我们调用getAllMedicines() 方法时,尝试在Patient 表中检索patients 的列表。在 99% 的情况下,我们只需要所有药物而不是患者名单,如果我们需要,我们可以加入并获得它!
那么这背后的原因是什么?或者我们是否也应该为 JDBC 保持相同的行为?
【问题讨论】:
-
patient列表通常会延迟加载,这意味着它只会在需要时读取数据。第二种方式包含您的数据,就像您通常在 OO 程序中编写它一样 -
@ScaryWombat:是的,我知道。我的问题是为什么我们不在 JDBC 中做同样的事情?我认为它根本没用。
-
您没有在 JDBC 中执行此操作的唯一原因是因为 您 没有在 JDBC 中执行此操作。 您可以完全控制您想要的操作方式,因此您可以通过将 MedicineBean 的
int idPatient替换为PatientBean patient并将List<MedicineBean> medicines添加到 PatientBean 来实现。这取决于它们的具体使用方式,这是另一种方法。 -
@Andreas: 好了.. 使用
Hibernate会导致我的REST API 出现严重问题,出现failed to lazily initialize collection错误,因为这种不必要的加载其他内容的尝试。我在 Hibernate 的 JBOSS 站点建议中尝试了所有内容,完全没有用。我更喜欢在MedicineBean中使用int idPatient而不是PatientBean patient,因为如果需要,我总是可以使用连接。 -
您始终可以选择使用轻量级 O/RM 库而不是 Hibernate。这样,您仍然可以获得 O/RM 的强大功能和灵活性,而不会产生 Hibernate 的开销(以及其他开销)。
标签: java mysql database hibernate jdbc