Hibernate的目的是帮助我们更好地持久化实体(Entity)。
实体与实体的间的关系一般有3种。
1对1:比如一个人有也只会有一个自己的详细信息,可以对应Person 和 PersonDetail类,Person与PersonDetail是1对1的关联。
1对多:比如一个大学可以有很多的学生,可以对应College和Student类,College和Student是1对多的关联。
多对多:比如有好几项任务,每个人可以接多个任务,一个任务可以由多人做,对应于Event 和 Delegate, Event和Delegate是多对多的关联。
实体有这些关系,我们希望Hibernate也能帮助我们处理这些关系。
hibernate处理1对1,Person和PersonDetail类:
核心的步骤有3步:(比如Person ->PersonDetail建立关联)
1. 将想要关联的类的实例作为私有变量:
private PersionDetail pDetail;
2. 在pDetail的get函数前加OneToOne标注,这个标注有2个属性 cascade 和 fetch
cascade指明如果person记录被操作了,pDetail记录要不要进行相应操作。
fetch指明如果person记录load进来了,关联的pDetail记录要不要load,默认load。
3. Person会默认创建执行PersonDetail的外键,我们可以给它一个新的名字(pDetail_FK)帮助我们理解代码。
Person.java
package com.hibernate.onetoonemapping;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Person {
private int personId;
private String personName;
private PersionDetail pDetail;//add PersonDetail instance to create a relation
@OneToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)//cascade: if person record is manipulated (deleted),
//person detail record will also be manipulated, fetch: if fetch person record, need to fetch person detail record?
@JoinColumn(name="pDetail_FK") //Person will have a foreign key refer to PersonDetail record
public PersionDetail getpDetail() {
return pDetail;
}
public void setpDetail(PersionDetail pDetail) {
this.pDetail = pDetail;
}
@Id
@GeneratedValue
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
}
PersonDetail.java
package com.hibernate.onetoonemapping;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class PersionDetail {
private int personDetailId;
private String zipCode;
private String job;
private double income;
//generate bi-directional relationship
private Person Person;
@OneToOne(mappedBy="pDetail", cascade=CascadeType.ALL)
public Person getPerson() {
return Person;
}
public void setPerson(Person person) {
Person = person;
}
@Id
@GeneratedValue
@Column(name="detailId_PK")
public int getPersonDetailId() {
return personDetailId;
}
public void setPersonDetailId(int personDetailId) {
this.personDetailId = personDetailId;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public double getIncome() {
return income;
}
public void setIncome(double income) {
this.income = income;
}
}
TestPerson.java
package com.hibernate.onetoonemapping;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class TestPerson {
public static void main(String[] args) {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(Person.class);// ask hibernate to persistent this class
config.addAnnotatedClass(PersionDetail.class);// ask hibernate to persistent this class
config.configure();//default will read hibernate.cfg.xml
new SchemaExport(config).create(true, true);//create table, first Boolean means print sql to the log file, second Boolean means execute sql
//insert record
SessionFactory factory = config.buildSessionFactory();
Session session = factory.getCurrentSession();
session.beginTransaction();
PersionDetail alexDetail = new PersionDetail();
alexDetail.setZipCode("abc");
alexDetail.setJob("Programmer");
alexDetail.setIncome(10000);
Person alex = new Person();
alex.setPersonName("Alex");
alex.setpDetail(alexDetail);
session.save(alex);
// no need if we set cascadeType
// session.save(alexDetail);
session.getTransaction().commit();//will execute sql
}
}