`
SIHAIloveYAN
  • 浏览: 119891 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类

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

 
阅读更多

1.1Hibernate关联关系的映射

1.1.1实体之间的关系:

实体之间有三种关系:

* 一对多:

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

* 建表原则:

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


* 多对多:

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

* 建表原则:

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


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

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

* 建表原则:

* 唯一外键:

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

* 主键对应:

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

1.1.2Hibernate中一对多的配置

第一步:

* 创建两个实体:

* 客户实体:

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.3Hibernate中级联保存的效果:

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

cascade=”save-update”

级联方向性:

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

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

1.1.4Hibernate中级联删除的效果:

cascade=”delete”

1.1.5Hibernate中的级联取值:

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.7Hibernate的多对多的配置:

第一步:创建实体类:

学生的实体:

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 one-to-one 一对一唯一外键关联映射_单向 and 双向

    在Hibernate中,一对一唯一外键关联映射是指两个实体之间的关联关系,其中一个实体作为外键,另一个实体作为关联目标。这种关联方式可以分为单向关联和双向关联两种。 单向关联是指一个实体作为外键,关联到另一个...

    Hibernate one-to-many / many-to-one关系映射

    在Java的持久化框架Hibernate中,关系映射是数据库对象之间的关联方式,它允许我们将复杂的数据库结构映射到Java对象上。"Hibernate one-to-many / many-to-one关系映射"是两个基本的关系类型,用于表示实体间的关联...

    hibernate many-to-many级联保存,级联更新,级联删除

    在Java的持久化框架Hibernate中,Many-to-Many关系是一种常见的数据库表之间的关联方式,它表示一个实体可以与多个其他实体进行关联,反之亦然。本文将深入探讨如何在Hibernate中处理Many-to-Many关系的级联保存、...

    hibernate5--3.映射关系

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者使用面向对象的方式来操作数据库。本文将深入探讨Hibernate5中的映射关系,主要包括多对多(Many-to-Many)和一对多(One-to-Many)...

    hibernate-release-5.2.10

    7. **关联映射**:包括一对一(@OneToOne)、一对多(@OneToMany)、多对一(@ManyToOne)、多对多(@ManyToMany)关系的映射,方便处理对象间的关联关系。 8. **延迟加载**:Hibernate的懒加载策略可以在需要时才...

    Hibernate映射一对多关联关系

    ### Hibernate映射一对多关联关系 #### 知识点概览 - **概念解析**:一对多(One-to-Many)关联关系的概念及其在Hibernate中的实现方式。 - **域模型设计**:创建具有一个实体与多个实体关联的域模型。 - **关系...

    Hibernate ORM - 继承关联关系之union-subclass

    在Java世界中,ORM(Object-Relational Mapping)框架如Hibernate是将数据库关系模型与对象模型之间进行映射的关键工具,极大地简化了数据库操作。本文将深入探讨Hibernate ORM中的一个特定概念——继承关联关系的...

    HIBERNATE - 符合Java习惯的关系数据库持久化

    关联映射是对象关系映射中另一重要概念,主要包括: 1. **单向关联**:实体类之间存在依赖关系,但仅有一方维护关联信息。 2. **多对一关联**:一个实体可能属于另一个实体的多个实例。 3. **一对一关联**:两个...

    hibernate关联映射详解

    hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,包含4个说明文档,分别详细解说了hibernate关联映射的关联关系,...

    hibernate 全面学习->hibernate 关联映射学习

    总的来说,这个压缩包提供了丰富的Hibernate关联映射的学习资源,涵盖了从基础到进阶的各种关联类型。通过学习这些示例,你将能够熟练掌握如何在Java项目中使用Hibernate进行数据持久化,并灵活地处理各种数据库关系...

    hibernate3.5.0-final下载链接

    Hibernate 是一个开源的对象关系映射(Object Relational Mapping,ORM)框架,它允许开发者将 Java 对象映射到数据库表,并支持多种数据库管理系统(Database Management Systems,DBMS)。Hibernate 3.5.0-Final ...

    Hibernate_实体关联关系映射--学习总结

    Hibernate的实体关联映射是其核心功能之一,它通过灵活的配置来适应不同场景下的数据持久化需求。通过对一对一、一对多、多对多等映射关系的熟练掌握和灵活运用,可以有效地处理复杂的实体关系,提高开发效率和应用...

    hibernate实体关联关系映射

    ### Hibernate实体关联关系映射详解 #### 一、引言 Hibernate作为一种强大的对象关系映射(Object Relational Mapping,简称ORM)框架,在Java开发领域扮演着极其重要的角色。它不仅简化了持久化层的开发工作,...

    Hibernate 关联关系映射分类

    在深入探讨Hibernate关联关系映射分类之前,我们首先简要回顾一下Hibernate框架的基本概念。Hibernate是一种持久层框架,主要用于Java应用程序中的对象关系映射(ORM),它能够将面向对象的数据模型转换为数据库中的...

    Hibernate ORM - 一对多双向关联关系

    标题“Hibernate ORM - 一对多双向关联关系”指的是在数据库建模中,Hibernate ORM(对象关系映射)框架如何处理一个实体类(如User)与多个实体类(如Article)之间的关系。在这种关系中,一个用户可以拥有多个文章...

    Hibernate教程-最全-最好_204页

    3. **对象关系映射(ORM)**:深入解析Hibernate的XML映射文件(hbm.xml),包括字段映射、主键生成策略、关联映射(一对一、一对多、多对一、多对多)等。 4. **实体管理**:介绍Entity类的定义,探讨@Annotations...

    Hibernate ORM - 一对一连接表关联关系

    标题"Hibernate ORM - 一对一连接表关联关系" 提示我们,这里主要讨论的是Hibernate ORM框架在处理数据库中一对一(One-to-One)关联映射的方法。Hibernate是一个流行的Java对象关系映射(ORM)工具,它允许开发者用...

    Hibernate集合映射与关联关系

    本主题将深入探讨Hibernate集合映射与关联关系,包括"student与Score的Map集合关系"、"student与class的多对一"以及"一对多映射"的概念。 首先,让我们理解一下Hibernate中的集合映射。在关系型数据库中,一个实体...

Global site tag (gtag.js) - Google Analytics