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

2023-12-16 04:48

本文主要是介绍8.1.2 Hibernate:一对一双向关联(bidirectional),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

运行测试,数据库表 phonephone_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();
}

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

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

运行测试,数据库表 phonephone_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();
}

运行测试,数据库表 phonephone_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
----------------------------------------------
......

这篇关于8.1.2 Hibernate:一对一双向关联(bidirectional)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499152

相关文章

MySQL复合查询从基础到多表关联与高级技巧全解析

《MySQL复合查询从基础到多表关联与高级技巧全解析》本文主要讲解了在MySQL中的复合查询,下面是关于本文章所需要数据的建表语句,感兴趣的朋友跟随小编一起看看吧... 目录前言:1.基本查询回顾:1.1.查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J1.2.按照部门

SQL表间关联查询实例详解

《SQL表间关联查询实例详解》本文主要讲解SQL语句中常用的表间关联查询方式,包括:左连接(leftjoin)、右连接(rightjoin)、全连接(fulljoin)、内连接(innerjoin)、... 目录简介样例准备左外连接右外连接全外连接内连接交叉连接自然连接简介本文主要讲解SQL语句中常用的表

如何高效移除C++关联容器中的元素

《如何高效移除C++关联容器中的元素》关联容器和顺序容器有着很大不同,关联容器中的元素是按照关键字来保存和访问的,而顺序容器中的元素是按它们在容器中的位置来顺序保存和访问的,本文介绍了如何高效移除C+... 目录一、简介二、移除给定位置的元素三、移除与特定键值等价的元素四、移除满足特android定条件的元

mysql关联查询速度慢的问题及解决

《mysql关联查询速度慢的问题及解决》:本文主要介绍mysql关联查询速度慢的问题及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql关联查询速度慢1. 记录原因1.1 在一次线上的服务中1.2 最终发现2. 解决方案3. 具体操作总结mysql

MYSQL关联关系查询方式

《MYSQL关联关系查询方式》文章详细介绍了MySQL中如何使用内连接和左外连接进行表的关联查询,并展示了如何选择列和使用别名,文章还提供了一些关于查询优化的建议,并鼓励读者参考和支持脚本之家... 目录mysql关联关系查询关联关系查询这个查询做了以下几件事MySQL自关联查询总结MYSQL关联关系查询

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

java面试常见问题之Hibernate总结

1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象。) Ø  OID检索(按照对象的OID来检索对象。) Ø  HQL检索(使用面向对象的HQL查询语言。) Ø  QBC检索(使用QBC(Qurey By Criteria)API来检索对象。 QBC/QBE离线/在线) Ø  本地SQL检索(使用本地数据库的SQL查询语句。) 包括Hibern

org.hibernate.hql.ast.QuerySyntaxException:is not mapped 异常总结

org.hibernate.hql.ast.QuerySyntaxException: User is not mapped [select u from User u where u.userName=:userName and u.password=:password] 上面的异常的抛出主要有几个方面:1、最容易想到的,就是你的from是实体类而不是表名,这个应该大家都知道,注意

Caused by: org.hibernate.MappingException: Could not determine type for: org.cgh.ssh.pojo.GoodsType,

MappingException:这个主要是类映射上的异常,Could not determine type for: org.cgh.ssh.pojo.GoodsType,这句话表示GoodsType这个类没有被映射到

Hibernate框架中,使用JDBC语法

/*** 调用存储过程* * @param PRONAME* @return*/public CallableStatement citePro(final String PRONAME){Session session = getCurrentSession();CallableStatement pro = session.doReturningWork(new ReturningWork<C