利用Hibernate可以很方便地将对象持久化。但有时候,我们想要将一个class持久化成2张表,这往往是为了数据库的范式需求。
而有时候,我们可能希望将2个class持久化到一张表中去。
利用Hibernate可以很方便的实现。
1. One class to two table
比如我们有一个Cusutomer 类,有以下这些属性,我们想要让customerId, customerName放到一张表中去,其他的属性放到CustomerDetail表中去。
private int customerId;
private String customerName;
private String customerAddress;
private int creditScore;
private int rewardPoints;
为了实现这个,我们需要告诉hibernate我们要创建哪两张表和class属性分别属于哪个表。
package com.hibernate.chapter2;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SecondaryTable;
import javax.persistence.Table;
@Entity
@Table(name="Customer")
@SecondaryTable(name="CustomerInfo")
public class Customer {
private int customerId;
private String customerName;
private String customerAddress;
private int creditScore;
private int rewardPoints;
@Id
@GeneratedValue
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
@Column(table="CustomerInfo")
public String getCustomerAddress() {
return customerAddress;
}
public void setCustomerAddress(String customerAddress) {
this.customerAddress = customerAddress;
}
@Column(table="CustomerInfo")
public int getCreditScore() {
return creditScore;
}
public void setCreditScore(int creditScore) {
this.creditScore = creditScore;
}
@Column(table="CustomerInfo")
public int getRewardPoints() {
return rewardPoints;
}
public void setRewardPoints(int rewardPoints) {
this.rewardPoints = rewardPoints;
}
}
在上面的代码中我们要生成2个表,Customer 和 CustomerInfo。同时指明了某些column要放到CustomerInfo表中。
不指明,就是默认放到第一张表中去。
最后我们看生成的表的情况:Customer的主键是customerId,CustomerInfo的外键是Customer表中的customerId。
2. Two class to one table
比如我们有2个class:
School:
private int schoolId;
private String schoolName;
SchoolDetail
private String schoolAddress;
private boolean isPublicSchool;
private int studentCount;
我们想要将这两个class持久化到同一张表中去。
我们先想想,如果没有hibernate的话,我们会怎么实现。
在创建表的时候,我们想把2个class中属性都作为table的column。
在insert record的时候,我们会将2个class中的属性值都放在一起insert。
hibernate的实现也是类似,它是将一个class当做主class,将另一个class相放到这个主class中去(embed)。
主class School.java代码:
package com.hibernate.chapter3;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class School {
private int schoolId;
private String schoolName;
@Embedded
private SchoolDetail schoolDetail;
@Id
@GeneratedValue
public int getSchoolId() {
return schoolId;
}
public void setSchoolId(int schoolId) {
this.schoolId = schoolId;
}
public String getSchoolName() {
return schoolName;
}
public void setSchoolName(String schoolName) {
this.schoolName = schoolName;
}
public SchoolDetail getSchoolDetail() {
return schoolDetail;
}
public void setSchoolDetail(SchoolDetail schoolDetail) {
this.schoolDetail = schoolDetail;
}
}
嵌入的class SchoolDetail.java
package com.hibernate.chapter3;
import javax.persistence.Embeddable;
@Embeddable
public class SchoolDetail {
private String schoolAddress;
private boolean isPublicSchool;
private int studentCount;
public String getSchoolAddress() {
return schoolAddress;
}
public void setSchoolAddress(String schoolAddress) {
this.schoolAddress = schoolAddress;
}
public int getStudentCount() {
return studentCount;
}
public void setStudentCount(int studentCount) {
this.studentCount = studentCount;
}
public boolean isPublicSchool() {
return isPublicSchool;
}
public void setPublicSchool(boolean isPublicSchool) {
this.isPublicSchool = isPublicSchool;
}
}
insert record 代码:
package com.hibernate.chapter3;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class TestSchool {
public static void main(String[] args) {
AnnotationConfiguration config = new AnnotationConfiguration();
config.addAnnotatedClass(School.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();
SchoolDetail schoolDetial = new SchoolDetail();
schoolDetial.setSchoolAddress("Shanghai");
schoolDetial.setPublicSchool(true);
schoolDetial.setStudentCount(500);
School school = new School();
school.setSchoolName("school name");
school.setSchoolDetail(schoolDetial);
session.save(school);//associate alex instance with hibernate
session.getTransaction().commit();//will execute sql
}
}