hibernate教程--关联关系的映射详解
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教程--关联关系的映射详解相关推荐
- hibernate教程--关联关系的映射
1.1Hibernate关联关系的映射 1.1.1实体之间的关系: 实体之间有三种关系: * 一对多: * 一个用户,生成多个订单,每一个订单只能属于一个用户. * 建表原则: * 在多的一方创建一个 ...
- hibernate教程--抓取策略详解
Hibernate的抓取策略 1.1. 区分延迟和立即检索: 立即检索: * 当执行某行代码的时候,马上发出SQL语句进行查询. * get() 延迟检索: * 当执行某行代码的时候,不会马上发出SQ ...
- hibernate教程--持久化类状态详解
一. Hibernate的持久化类状态: 1.1 Hibernate的持久化类状态 持久化类:就是一个实体类 与 数据库表建立了映射. Hibernate为了方便管理持久化类,将持久化类分成了三种状态 ...
- Hibernate对象关系映射详解之一对多关系映射
Hibernate对象关系映射详解之"一对多"关系映射 之前学习Hibernate框架的时候,对这七大关系映射一直是云里雾里的,虽然可以仿照写出代码,但是不能独立编写出来.鉴于工作 ...
- ElasticSearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解...
墨墨导读:之前我们分享了ElasticSearch最全详细使用教程:入门.索引管理.映射详解,本文详细介绍ElasticSearch的索引别名.分词器.文档管理.路由.搜索详解. 一.索引别名 1. ...
- ElasticSearch最全详细使用教程:入门、索引管理、映射详解
墨墨导读:本文介绍了ElasticSearch的必备知识:从入门.索引管理到映射详解. 一.快速入门 1. 查看集群的健康状况http://localhost:9200/_cat http://loc ...
- elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解
一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 ...
- FluentNHibernate之基本映射详解
最近在做项目的时候用到了NHibernate,使用它并不困难,但是很麻烦.如果我的数据库有几百张表如果想要一个个的映射岂不是很麻烦,所以这种情况下使用NHibernate就会很笨重,虽然这个ORM框架 ...
- Nmap扫描教程之基础扫描详解
Nmap扫描教程之基础扫描详解 Nmap扫描基础扫描 当用户对Nmap工具了解后,即可使用该工具实施扫描.通过上一章的介绍,用户可知Nmap工具可以分别对主机.端口.版本.操作系统等实施扫描.但是,在 ...
最新文章
- [JavaScript] Map类型在JavaScript中的使用
- 如何跟程序员谈一场没有Bug的恋爱
- OpenGL绘制带有索引的矩形的实例
- define 字符串_C++如何使用define关键字以便使用中文编程?
- archlinux php imagemagick,如何用ImageMagick将SVG转换为PNG?
- java close wait过多_HttpClient当HTTP连接的时候出现大量CLOSE_WAIT连接
- 60-179-024-使用-TypeInfo-Flink类型系统TypeIinformation
- css字体倾斜角度_css如何实现渐变效果?css背景色渐变与文字渐变效果的实现(代码实例)...
- 阿里消息中间件ONS消息乱序问题(二)
- Word怎么转PDF?看完这篇你就知道了
- 华为服务器忘记系统密码忘了,服务器忘记密码重置
- t430服务器查看raid状态,dell t430 raid1教程
- Untracked Files Prevent Merge Move or commit them before merge 使用Idea clone下来的项目运行后,无法pull更新
- 基于 HTML5 Canvas 的简易 2D 3D 编辑器
- Html5常见面试题总结
- 高效能创业者的七项习惯
- python编程新手常犯的错误_Python程序员常犯的10个错误
- 论语(原文注音, 注释, 译文, 评析) 打印版
- oracle的服务配置
- 青岛学计算机哪些学校好,青岛计算机专业哪些学校好