1 定义映射类
1.1 表 phone
的映射类定义:
package hibernate;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "phone")
public class Phone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "imei")
private String imei;
@Column(name = "number")
private String number;
@OneToOne(mappedBy = "phone", orphanRemoval = true, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private PhoneDetail phoneDetail;
public Phone() {}
public Phone(String imei, String number) {
this.imei = imei;
this.number = number;
}
// 省略 Getters 和 Setters ...
}
1.2 表 phone_detail
的映射类定义:
package hibernate;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name = "phone_detail")
public class PhoneDetail {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private int id;
@Column(name = "manufacturer")
private String manufacturer;
@Column(name = "model")
private String model;
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinColumn(name = "phone_id")
private Phone phone;
public PhoneDetail() {}
public PhoneDetail(String manufacturer, String model) {
this.manufacturer = manufacturer;
this.model = model;
}
// 省略 Getters 和 Setters ...
}
2 测试
2.1 新增
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Phone phone = new Phone("812345678912345", "18012345678");
PhoneDetail phoneDetail = new PhoneDetail("XXX", "XXX-2017");
phone.setPhoneDetail(phoneDetail);
phoneDetail.setPhone(phone);
session.save(phone);
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,数据库表 phone
和 phone_detail
中新插入了两条数据(日志省略)。
将单元测试中 session.save(phone);
替换成 session.save(phoneDetail);
,测试结果相同。
由此可见,双向关联的任一方都维护级联关系。
2.2 删除
基于以上测试新增的数据进行删除测试。
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Phone phone = (Phone) session.createQuery(" FROM Phone").list().get(0);
session.delete(phone);
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,数据库表 phone
和 phone_detail
中对应记录被删除(日志省略)。
将单元测试中
Phone phone = (Phone) session.createQuery(" FROM Phone").list().get(0);
session.delete(phone);
替换成
PhoneDetail phoneDetail = (PhoneDetail) session.createQuery(" FROM PhoneDetail").list().get(0);
session.delete(phoneDetail);
测试结果相同。
2.3 更新
基于新增测试的数据进行更新测试。
2.3.1 通过 Phone
查找关联的 PhoneDetail
并执行级联更新
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Phone phone = (Phone) session.createQuery(" FROM Phone").list().get(0);
phone.setImei("898765432198765");
phone.setNumber("17712345678");
PhoneDetail phoneDetail = phone.getPhoneDetail();
phoneDetail.setManufacturer("YYY");
phoneDetail.setModel("YYY-2017");
session.save(phone);
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,数据库表 phone
和 phone_detail
中对应记录级联更新成功(日志省略)。
将单元测试中 session.save(phone);
替换成 session.save(phoneDetail);
,测试结果相同,同样级联更新成功。
2.3.1 通过 PhoneDetail
查找关联的 Phone
并执行级联更新
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
PhoneDetail phoneDetail = (PhoneDetail) session.createQuery(" FROM PhoneDetail").list().get(0);
phoneDetail.setManufacturer("YYY");
phoneDetail.setModel("YYY-2017");
Phone phone = phoneDetail.getPhone();
phone.setImei("898765432198765");
phone.setNumber("17712345678");
session.save(phoneDetail);
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,数据库表 phone
和 phone_detail
中对应记录级联更新成功(日志省略)。
将单元测试中 session.save(phoneDetail);
替换成 session.save(phone);
,测试结果相同,同样级联更新成功。
2.4 查询
基于新增测试的数据进行查询测试。
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Phone phone = (Phone) session.createQuery(" FROM Phone").list().get(0);
System.out.println("-------------------- From Phone --------------------");
System.out.println("Phone ID : " + phone.getId());
System.out.println("Phone IMEI : " + phone.getImei());
System.out.println("Phone Number : " + phone.getNumber());
System.out.println("Binded Phone Detail ID : " + phone.getPhoneDetail().getId());
System.out.println("Binded Phone Detail Manufacture : " + phone.getPhoneDetail().getManufacturer());
System.out.println("Binded Phone Detail Model : " + phone.getPhoneDetail().getModel());
System.out.println("----------------------------------------------");
PhoneDetail phoneDetail = (PhoneDetail) session.createQuery(" FROM PhoneDetail").list().get(0);
System.out.println("-------------------- From Phone Detail --------------------");
System.out.println("Phone Detail ID : " + phoneDetail.getId());
System.out.println("Phone Detail Manufacture : " + phoneDetail.getManufacturer());
System.out.println("Phone Detail Model : " + phoneDetail.getModel());
System.out.println("Binded Phone ID : " + phoneDetail.getPhone().getId());
System.out.println("Binded Phone IMEI : " + phoneDetail.getPhone().getImei());
System.out.println("Binded Phone Number : " + phoneDetail.getPhone().getNumber());
System.out.println("----------------------------------------------");
transaction.commit();
session.close();
sessionFactory.close();
}
运行测试,打印结果:
......
-------------------- From Phone --------------------
Phone ID : 15
Phone IMEI : 898765432198765
Phone Number : 17712345678
Binded Phone Detail ID : 11
Binded Phone Detail Manufacture : YYY
Binded Phone Detail Model : YYY-2017
----------------------------------------------
......
-------------------- From Phone Detail --------------------
Phone Detail ID : 11
Phone Detail Manufacture : YYY
Phone Detail Model : YYY-2017
Binded Phone ID : 15
Binded Phone IMEI : 898765432198765
Binded Phone Number : 17712345678
----------------------------------------------
......