8.1.2 Hibernate:一对一双向关联(bidirectional)

来源:互联网 发布:淘宝客推广大师官网 编辑:程序博客网 时间:2024/06/08 09:29

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 新增

@Testpublic 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();}

运行测试,数据库表 phonephone_detail 中新插入了两条数据(日志省略)。

将单元测试中 session.save(phone); 替换成 session.save(phoneDetail);,测试结果相同。

由此可见,双向关联的任一方都维护级联关系。

2.2 删除
基于以上测试新增的数据进行删除测试。

@Testpublic 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();}

运行测试,数据库表 phonephone_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 并执行级联更新

@Testpublic 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();}

运行测试,数据库表 phonephone_detail 中对应记录级联更新成功(日志省略)。

将单元测试中 session.save(phone); 替换成 session.save(phoneDetail);,测试结果相同,同样级联更新成功。

2.3.1 通过 PhoneDetail 查找关联的 Phone 并执行级联更新

@Testpublic 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();}

运行测试,数据库表 phonephone_detail 中对应记录级联更新成功(日志省略)。

将单元测试中 session.save(phoneDetail); 替换成 session.save(phone);,测试结果相同,同样级联更新成功。

2.4 查询
基于新增测试的数据进行查询测试。

@Testpublic 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 : 15Phone IMEI : 898765432198765Phone Number : 17712345678Binded Phone Detail ID : 11Binded Phone Detail Manufacture : YYYBinded Phone Detail Model : YYY-2017----------------------------------------------......-------------------- From Phone Detail --------------------Phone Detail ID : 11Phone Detail Manufacture : YYYPhone Detail Model : YYY-2017Binded Phone ID : 15Binded Phone IMEI : 898765432198765Binded Phone Number : 17712345678----------------------------------------------......
原创粉丝点击