1.1 Hibernate关联关系的映射

1.1.1 实体之间的关系:

实体之间有三种关系:

* 一对多:

* 一个用户,生成多个订单,每一个订单只能属于一个用户.

* 建表原则:

* 在多的一方创建一个字段,作为外键,指向一的一方的主键.

* 多对多:

* 一个学生可以选择多门课程,一个课程可以被多个学生选择.

* 建表原则:

* 创建第三张表,中间表至少有两个字段,分别作为外键指向多对多双方主键.

* 一对一:(特殊.最少.)

* 一个公司只能有一个注册地址,一个注册地址,只能被一个公司使用.(否则将两个表建到一个表.)

* 建表原则:

* 唯一外键:

* 一对一的双方,假设一方是多的关系.需要在多的一方创建一个字段,作为外键.指向一的一方的主键.但是在外键添加一个unique.

* 主键对应:

* 一对一的双方,通过主键进行关联.

1.1.2 Hibernate中一对多的配置

第一步:

* 创建两个实体:

* 客户实体:

public class Customer {private Integer cid;private String cname;// 一个客户有多个订单.private Set<Order> orders = new HashSet<Order>();public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}public Set<Order> getOrders() {return orders;}public void setOrders(Set<Order> orders) {this.orders = orders;}}* 订单实体:public class Order {private Integer oid;private String addr;// 订单属于某一个客户.放置一个客户的对象.private Customer customer;public Integer getOid() {return oid;}public void setOid(Integer oid) {this.oid = oid;}public String getAddr() {return addr;}public void setAddr(String addr) {this.addr = addr;}public Customer getCustomer() {return customer;}public void setCustomer(Customer customer) {this.customer = customer;}}

第二步:建立映射:

Customer.hbm.xml

<hibernate-mapping><class name="com.sihai.hibernate3.demo2.Customer" table="customer"><!-- 配置唯一标识 --><id name="cid" column="cid"><generator class="native"/></id><!-- 配置普通属性 --><property name="cname" column="cname" length="20"/><!-- 建立映射 --><!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. --><set name="orders"><!-- <key>标签中column:用来描述一对多多的一方的外键的名称. --><key column="cno"></key><!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 --><one-to-many class="com.sihai.hibernate3.demo2.Order"/></set></class></hibernate-mapping>

Order.hbm.xml

<hibernate-mapping><class name="com.sihai.hibernate3.demo2.Order" table="orders"><!-- 配置唯一标识  --><id name="oid" column="oid"><generator class="native"/></id><!-- 配置普通属性 --><property name="addr" column="addr" length="50"/><!-- 配置映射 --><!--<many-to-one>标签name :关联对象的属性的名称.column:表中的外键名称.class:关联对象类的全路径--><many-to-one name="customer" column="cno" class="com.sihai.hibernate3.demo2.Customer"/></class></hibernate-mapping>

第三步:将映射放到核心配置文件中.

1.1.3 Hibernate中级联保存的效果:

级联:操作当前对象的时候,关联的对象如何处理.

cascade=”save-update”

级联方向性:

* 保存客户的时候,选择级联订单.

* 保存订单的时候,选择级联客户.

1.1.4 Hibernate中级联删除的效果:

cascade=”delete”

1.1.5 Hibernate中的级联取值:

none:不使用级联

save-update:保存或更新的时候级联

delete:删除的时候级联

all:除了孤儿删除以外的所有级联.

delete-orphan:孤儿删除(孤子删除).

* 仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.

* 当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.

all-delete-orphan:包含了孤儿删除的所有的级联.

1.1.6 双向维护产生多余的SQL:

配置inverse=”true”:在那一端配置.那么那一端放弃了外键的维护权.

* 一般情况下,一的一方去放弃.

cascade:操作关联对象.

inverse:控制外键的维护.

package com.sihai.hibernate3.demo2;import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;import com.sihai.utils.HibernateUtils;/*** 一对多的测试* @author sihai**/
public class HibernateTest2 {@Test// 区分cascade和inverse// 在Customer.hbm.xml中的<set>上配置 cascade="save-update" inverse="true"public void demo11(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();Customer customer = new Customer();customer.setCname("张三");Order order = new Order();order.setAddr("西三旗");customer.getOrders().add(order);// 客户是否存到数据库:存// 订单是否存到数据库:存 cascade="save-update".外键是null.session.save(customer);tx.commit();session.close();}@Test// 双向维护:自动更新数据库,产生多余的SQL.// 双方都有外键的维护能力.必须让其中一方放弃外键的维护权.(一般情况下都是一的放弃.)public void demo10(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();Customer customer = (Customer) session.get(Customer.class, 1);Order order = (Order) session.get(Order.class, 2);customer.getOrders().add(order);order.setCustomer(customer);tx.commit();session.close();}@Test// 孤儿删除:// 在Customer.hbm.xml中<set>上配置cascade="delete-orhpan"public void demo9(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 让1号客户与1号订单解除关系:Customer customer = (Customer) session.get(Customer.class, 1);Order order = (Order) session.get(Order.class, 1);customer.getOrders().remove(order);tx.commit();session.close();}@Test// 级联删除:删除订单的时候,级联删除客户.public void demo8(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();Order order = (Order) session.get(Order.class, 1);session.delete(order);tx.commit();session.close();}@Test// 级联删除:删除客户的时候级联删除订单.// 在Customer.hbm.xml的<set>标签上配置cascade="delete"public void demo7(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 级联删除:先查询,在删除的方式.Customer custoemr = (Customer) session.get(Customer.class, 1);session.delete(custoemr);tx.commit();session.close();}@Test// 删除一个客户:// 默认的情况下,将外键置为null,删除数据记录.public void demo6(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 删除的时候有两种:// 先查询在删除的情况:Customer customer = (Customer) session.get(Customer.class, 1);session.delete(customer);tx.commit();session.close();}@Test// 测试对象的导航关系:public void demo5(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 定义一个客户:Customer customer = new Customer();customer.setCname("金刚");// 定义三个订单Order order1 = new Order();order1.setAddr("西三旗");Order order2 = new Order();order2.setAddr("上地");Order order3 = new Order();order3.setAddr("五道口");order1.setCustomer(customer);customer.getOrders().add(order2);customer.getOrders().add(order3);// session.save(order1); // 共发送4条insert语句:// session.save(customer);// 共发送3条insert语句:session.save(order2);tx.commit();session.close();}@Test// 保存订单级联客户.// 在Order.hbm.xml中<many-to-one>配置cascade属性:级联保存public void demo4(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 定义客户:Customer customer = new Customer();customer.setCname("郭浩");// 定义订单:Order order = new Order();order.setAddr("西三旗中腾建华");order.setCustomer(customer);customer.getOrders().add(order);// 保存的时候只保存一方:session.save(order);tx.commit();session.close();}@Test// 保存客户级联订单.// <set>集合是客户的关联订单对象的集合.所以在<set>上配置一个属性:cascade="save-update"public void demo3(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 定义客户:Customer customer = new Customer();customer.setCname("郭浩");// 定义订单:Order order = new Order();order.setAddr("西三旗中腾建华");order.setCustomer(customer);customer.getOrders().add(order);// 保存的时候只保存一方:session.save(customer);tx.commit();session.close();}@Test// 保存客户和订单的时候,是否可以只保存其中的一方?不行的报一个异常:一个持久态对象关联一个瞬时的对象.public void demo2(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 定义客户:Customer customer = new Customer();customer.setCname("金刚");// 定义订单:Order order = new Order();order.setAddr("五道口");order.setCustomer(customer);customer.getOrders().add(order);// 保存的时候只保存一方:session.save(customer);tx.commit();session.close();}@Test// 向客户表插入一个客户,在订单表中插入两个订单.public void demo1(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 定义一个客户:Customer customer = new Customer();customer.setCname("郭浩");// 定义两个订单:Order order1 = new Order();order1.setAddr("西三旗中腾");Order order2 = new Order();order2.setAddr("西三旗金燕龙");// 建立关系:order1.setCustomer(customer);order2.setCustomer(customer);customer.getOrders().add(order1);customer.getOrders().add(order2);session.save(customer);session.save(order1);session.save(order2);tx.commit();session.close();}
}

1.1.7 Hibernate的多对多的配置:

第一步:创建实体类:

学生的实体:

public class Student {private Integer sid;private String sname;// 一个学生选择多门课程:private Set<Course> courses = new HashSet<Course>();public Integer getSid() {return sid;}public void setSid(Integer sid) {this.sid = sid;}public String getSname() {return sname;}public void setSname(String sname) {this.sname = sname;}public Set<Course> getCourses() {return courses;}public void setCourses(Set<Course> courses) {this.courses = courses;}}

课程的实体:

public class Course {private Integer cid;private String cname;// 一个课程被多个学生选择:private Set<Student> students = new HashSet<Student>();public Integer getCid() {return cid;}public void setCid(Integer cid) {this.cid = cid;}public String getCname() {return cname;}public void setCname(String cname) {this.cname = cname;}public Set<Student> getStudents() {return students;}public void setStudents(Set<Student> students) {this.students = students;}}

第二步建立映射:

Student.hbm.xml

<hibernate-mapping><class name="com.sihai.hibernate3.demo3.Student" table="student"><!-- 配置唯一标识 --><id name="sid" column="sid"><generator class="native"/></id><!-- 配置普通属性 --><property name="sname" column="sname" length="20"/><!-- 配置关联映射 --><!-- <set>标签 name:对应学生中的课程集合的名称   table:中间表名称. --><set name="courses" table="stu_cour"><!-- <key>中column写 当前类在中间表的外键.--><key column="sno"></key><!-- <many-to-many>中class:另一方类的全路径. column:另一方在中间表中外键名称--><many-to-many class="com.sihai.hibernate3.demo3.Course" column="cno"/></set></class></hibernate-mapping>

Course.hbm.xml

<hibernate-mapping><class name="com.sihai.hibernate3.demo3.Course" table="course"><!-- 配置唯一标识 --><id name="cid" column="cid"><generator class="native"/></id><!-- 配置普通属性 --><property name="cname" column="cname" length="20"/><!-- 配置与学生关联映射 --><!-- <set>中name:对应当前类中的学生的集合的名称  table:中间表的名称--><set name="students" table="stu_cour"><!-- <key>中column:当前类在中间表中外键 --><key column="cno"></key><!-- <many-to-many>中class:另一方的类全路径. column:另一方在中间表中外键名称 --><many-to-many class="com.sihai.hibernate3.demo3.Student" column="sno"/></set></class></hibernate-mapping>

第三步:将映射文件加入到核心配置文件中:


测试:

package com.sihai.hibernate3.demo3;import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;import com.sihai.utils.HibernateUtils;/*** 多对多的测试类:* * @author sihai* */
public class HibernateTest3 {@Test// 多对多的学生退选.public void demo4(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 查询一号学生Student student = (Student) session.get(Student.class, 1);Course course = (Course) session.get(Course.class, 2);student.getCourses().remove(course);tx.commit();session.close();}@Test// 级联删除:在多对多中很少使用.// 删除:删除学生同时删除学生关联选课public void demo3(){Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();Student student = (Student) session.get(Student.class, 3);session.delete(student);tx.commit();session.close();}@Test// 级联操作:级联保存:保存学生关联课程// 在Student.hbm.xml中配置<set>上 cascade="save-update"public void demo2() {Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 创建学生:Student student1 = new Student();student1.setSname("王五");// 创建课程:Course course1 = new Course();course1.setCname("PHP语言");student1.getCourses().add(course1);course1.getStudents().add(student1);session.save(student1);tx.commit();session.close();}@Test// 保存学生和课程.为学生选择一些课程:public void demo1() {Session session = HibernateUtils.openSession();Transaction tx = session.beginTransaction();// 创建学生:Student student1 = new Student();student1.setSname("张三");Student student2 = new Student();student2.setSname("李四");// 创建课程:Course course1 = new Course();course1.setCname("Java语言");Course course2 = new Course();course2.setCname("Android语言");// 张三选1号和2号课student1.getCourses().add(course1);student1.getCourses().add(course2);course1.getStudents().add(student1);course2.getStudents().add(student1);student2.getCourses().add(course1);course1.getStudents().add(student2);// 执行保存:session.save(student1);session.save(student2);session.save(course1);session.save(course2);tx.commit();session.close();}
}

hibernate教程--关联关系的映射详解相关推荐

  1. hibernate教程--关联关系的映射

    1.1Hibernate关联关系的映射 1.1.1实体之间的关系: 实体之间有三种关系: * 一对多: * 一个用户,生成多个订单,每一个订单只能属于一个用户. * 建表原则: * 在多的一方创建一个 ...

  2. hibernate教程--抓取策略详解

    Hibernate的抓取策略 1.1. 区分延迟和立即检索: 立即检索: * 当执行某行代码的时候,马上发出SQL语句进行查询. * get() 延迟检索: * 当执行某行代码的时候,不会马上发出SQ ...

  3. hibernate教程--持久化类状态详解

    一. Hibernate的持久化类状态: 1.1 Hibernate的持久化类状态 持久化类:就是一个实体类 与 数据库表建立了映射. Hibernate为了方便管理持久化类,将持久化类分成了三种状态 ...

  4. Hibernate对象关系映射详解之一对多关系映射

    Hibernate对象关系映射详解之"一对多"关系映射 之前学习Hibernate框架的时候,对这七大关系映射一直是云里雾里的,虽然可以仿照写出代码,但是不能独立编写出来.鉴于工作 ...

  5. ElasticSearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解...

    墨墨导读:之前我们分享了ElasticSearch最全详细使用教程:入门.索引管理.映射详解,本文详细介绍ElasticSearch的索引别名.分词器.文档管理.路由.搜索详解. 一.索引别名 1. ...

  6. ElasticSearch最全详细使用教程:入门、索引管理、映射详解

    墨墨导读:本文介绍了ElasticSearch的必备知识:从入门.索引管理到映射详解. 一.快速入门 1. 查看集群的健康状况http://localhost:9200/_cat http://loc ...

  7. elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解

    一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 ...

  8. FluentNHibernate之基本映射详解

    最近在做项目的时候用到了NHibernate,使用它并不困难,但是很麻烦.如果我的数据库有几百张表如果想要一个个的映射岂不是很麻烦,所以这种情况下使用NHibernate就会很笨重,虽然这个ORM框架 ...

  9. Nmap扫描教程之基础扫描详解

    Nmap扫描教程之基础扫描详解 Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在 ...

最新文章

  1. [JavaScript] Map类型在JavaScript中的使用
  2. 如何跟程序员谈一场没有Bug的恋爱
  3. OpenGL绘制带有索引的矩形的实例
  4. define 字符串_C++如何使用define关键字以便使用中文编程?
  5. archlinux php imagemagick,如何用ImageMagick将SVG转换为PNG?
  6. java close wait过多_HttpClient当HTTP连接的时候出现大量CLOSE_WAIT连接
  7. 60-179-024-使用-TypeInfo-Flink类型系统TypeIinformation
  8. css字体倾斜角度_css如何实现渐变效果?css背景色渐变与文字渐变效果的实现(代码实例)...
  9. 阿里消息中间件ONS消息乱序问题(二)
  10. Word怎么转PDF?看完这篇你就知道了
  11. 华为服务器忘记系统密码忘了,服务器忘记密码重置
  12. t430服务器查看raid状态,dell t430 raid1教程
  13. Untracked Files Prevent Merge Move or commit them before merge 使用Idea clone下来的项目运行后,无法pull更新
  14. 基于 HTML5 Canvas 的简易 2D 3D 编辑器
  15. Html5常见面试题总结
  16. 高效能创业者的七项习惯
  17. python编程新手常犯的错误_Python程序员常犯的10个错误
  18. 论语(原文注音, 注释, 译文, 评析) 打印版
  19. oracle的服务配置
  20. 青岛学计算机哪些学校好,青岛计算机专业哪些学校好

热门文章

  1. 拔掉网线时Socket的检查方法
  2. RDA8955中碰到的问题
  3. cryptogen (1)generate 生成证书举例
  4. (chap9 基于HTTP的功能追加协议) HTTP瓶颈
  5. C++(四)——类和对象(下)
  6. 现代密码学5.3--Hash and MAC
  7. 近世代数--置换群--判断置换的奇偶性
  8. buuctf LSB
  9. (23)逆向分析 MmIsAddressValid 函数(XP系统 10-10-12分页)
  10. 2020-11-26((《深入理解计算机系统》多级页表详解)补充)