Hibernate学习笔记(五) — 多对多关系映射

多对多关系映射

多对多建立关系相当于在第三张表中插入一行数据

多对多解除关系相当于在第三张表中删除一行数据

多对多修改关系相当于在第三张表中先删除后增加

多对多谁维护效率都一样。看需求

在实际开发过程中,多对多的映射关系比较常见。

学生选课示例,一个学生可以选多门课,一门课也可以由多个学生去选,这样就形成了多对多的映射关系

public class Student implements Serializable {

	private static final long serialVersionUID = 1L;
	private Long sid;
	private String name;
	private Set<Course> courses = new HashSet<Course>();

}
public class Course implements Serializable {

	private static final long serialVersionUID = 1L;
	private Long cid;
	private String name;
	private Set<Student> students = new HashSet<Student>();
}

*hbm.xml

<class name="Student" table="STUDENT">
		<id name="sid">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<set name="courses" table="student_courses"  inverse="false" cascade="save-update">
			<key column="sid"></key>
			<many-to-many class="Course" column="cid"></many-to-many>
		</set>
		<!-- 两个id的书写,要记牢 -->
	</class>
<class name="Course" table="COURSE">
		<id name="cid">
			<generator class="native"></generator>
		</id>
		<property name="name"></property>
		<!-- table第三张表的名字:不写会会默认生成,可能会出现两张第三张表 -->
		<set name="students" table="student_courses">
			<!--
				外键
			 -->
			<key column="cid"></key>
			<!--
				column:外键
			 -->
			<many-to-many class="Student" column="sid"></many-to-many>
		</set>
	</class>

测试类:

public class many2manyTest {

	private Session session;
	private Transaction transaction;

	@Before
	public void init(){
		session = HibernateUtils.openSession();
		transaction = session.beginTransaction();
	}

	/**
	 * 学生 级联操作
	 * 保存的学生的时候,级联保存课程
	 */
	@Test
	public void testSaveStudent_cascade_SaveCourse(){

		Student student = new Student();
		student.setName("A");
		Course course = new Course();
		course.setName("a");

		Set<Course> courses = new HashSet<Course>();
		Set<Student> students = new HashSet<Student>();

		courses.add(course);
		student.setCourses(courses);
		students.add(student);
		session.save(student);
		//session.save(course);
	}

	/**
	 * 已经存在一个学生,一个课程,关联两者关系
	 */
	@Test
	public void testBuildRelationship(){

		Student student = (Student) session.get(Student.class, 2L);
		Course course = (Course) session.get(Course.class, 2L);
		//System.out.println(student.getCourses().size()); //0,说明即使学生没有课程,Set<Course> hibernate来帮我们创建,前提是Student类是持久化的
															//建议类中定义Set<>时,直接new 出 hashSet
		/**
		 * student.getCourses().add(course);
			course.getStudents().add(student); //报错,只能有一个来进行添加操作,
				//从 学生来建立关系 或 从课程来建立关系  都可以
		 */
		student.getCourses().add(course);
	}

	/**
	 * 已经有一个课程,新建一个学生,建立关系
	 */
	@Test
	public void testSaveStudent_BuildR(){
		Course course = (Course) session.get(Course.class, 2L);
		Student student = new Student();
		student.setName("BB");
		//student.getCourses().add(course);//如果不定义Set<> = new HashSet<>,会空指针异常,3条sql
	/*	Set<Course> courses = new HashSet<Course>();
		courses.add(course);
		student.setCourses(courses);3条sql*/

//		course.getStudents().add(student);//4条sql

		student.getCourses().add(course);
		/**
		 * hibernate程序,效率与写法有很大关系
		 */
		session.save(student);
	}

	/**
	 * 一个学生从一门课程,转学 另一门课程
	 * sid为5的学生从课程2转到课程1
	 */
	@Test
	public void testTransform(){
		Student student = (Student) session.get(Student.class,5L);
		Course course = (Course) session.get(Course.class, 1L);
		Course course2 = (Course) session.get(Course.class, 2L);
		student.getCourses().remove(course2);//解除学生和cid为2的课程
		student.getCourses().add(course);//6条sql,jdbc只需update,这就是hibernate的坑爹之处
	}

	/**
	 * 解除一个学生和该学生所学的所有的课程之间的关系
	 */
	@Test
	public void testRealseAllR(){
		/**
		 * 解除sid为1的学生和所有的课程之间的关系
		 */
		Student student = (Student)session.get(Student.class, 1L);
		student.setCourses(null);
		transaction.commit();
		session.close();
	}

	/**
	 * 解除一个学生和所有的课程之间的关系,再建立一些课程之间的关系
	 */
	@Test
	public void testRealseAllRAndBuildR(){
		Student student = (Student)session.get(Student.class, 1L);

		/**
		 * 因为 再建立一些课程之间的关系,所以用Set,千万不要一个一个add
		 */
		Set<Course> courses = new HashSet<Course>();
		Course course = (Course)session.get(Course.class, 3L);
		courses.add(course);
		//把原来的student中的courses给覆盖掉了
		student.setCourses(courses);
	}

	@After
	public void destory(){
		transaction.commit();
		session.close();
	}
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-11 23:10:15

Hibernate学习笔记(五) — 多对多关系映射的相关文章

深入浅出Hibernate(二)多对一关系映射

学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比如下图所示的员工和部门之间的关系,那么这种关系在Hibernate中如何映射呢?让我用一个小Demo来详细讲解. 建立映射分为以下几步: 1.设计domain对象Department.Employee,代码如下: package cn.itcast.hibernate.domain; public class Department { private int id; private String name;

《Hibernate学习笔记八》:组件映射

<Hibernate学习笔记八>:组件映射 前面介绍了一对一的单向.双向外键关联,例如,学生证和学生是一个一对一的关系.这篇博文主要是介绍下组件映射,即一个是另一个的一部分,例如,学生证的信息也可以作为学生信息的一部分,即在数据库中只存在学生一个表,而不是有学生和学生证两个表,并且这两个表中有一个一对一的关联关系. 如下: 有人或许会说,那我们就将学生和学生证的信息写在一个类中,则就不需要组件映射了,确实可以这样,但是,根据类的设计原则,我们一般都会将其设计为两个类,然后将学生证的信息作为一个

--------Hibernate框架之双向多对多关系映射

今天跟大家分享下在Hibernate中双向的多对多的映射关系 这次我们以项目和员工举个栗子,因为大家可以想象得到,在真实的环境下,一个项目肯定是对应着多个员工的,这毫无疑问, 那么同时,一个比较牛员工也能同时参与多个项目的开发,这就体现了双向多对多的关系. 首先呢,我们得弄清楚在底层数据库中表与表之间的关系,我们创建一个员工表(Employee)和项目表(Project)毫无疑问,那么我们要怎么体现出多对多的关系呢? 当然有很多种方法,这里我以单独提出一张关系表为例,也就是说,我单独创建一张表来

hibernate学习笔记(五)

接着上一篇的说hibernate关联映射关系中的一对多单向的,一对多怎么说呢?很多很多的这样的例子,一个班级多个学生,一个发票抬头下面有多间物品等等,一对多单向的就是通过一得一端来获取多的一端的信息. 一对多和多对一大体上查不了多少,多对一是由多的一端来控制关系,那么一对多就是一得一端来控制关系.那么怎么来实现呢,其实只需要在一得一端加一个set<T>属性即可,T代表的就是多的一端的实体类,配置OneToMany即可.下面上例子(才看到有插入代码的,不用那么麻烦的上传图片了): 1 packa

Hibernate学习笔记五:反向工程快速开发

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6768513.html  一:反向工程 Myeclipse提供由 数据库表 生成 java pojo 和 hibernate映射文件 的功能,这就是反向工程. 二:由反向工程得到POJO类与映射文件 1:点击开发界面右上角的 >,选择 Database Explorer界面. 2:在空白处右键呼出菜单,选择 New. 在如下界面,依次:选择数据库类型.命名这个连接.数据库路径.账户.密码.添加驱动包. 3:双

【Java EE 学习第46天】【Hibernate学习第三天】【多对多关系映射】

一.多对多关系概述 以学生和课程之间的关系为例. 1.在多对多关系中涉及到的表有三张,两张实体表,一张专门用于维护关系的表. 2.多对多关系中两个实体类中应当分别添加对方的Set集合的属性,并提供set和get方法. 3.在配置映射文件的时候较一对多关系复杂. 二.映射文件 <set name="students" table="course_stu" cascade="save-update" inverse="true&quo

《Hibernate学习笔记十二》学生、课程、分数关系的设计与实现

<Hibernate学习笔记十二>学生.课程.分数关系的设计与实现 这个马士兵老师的Hibernate视频学习的一个题目,这里面要用到多对多.多对一的关联关系以及联合主键,因此觉得挺好的,自己写篇博文来记录下. 先考虑数据库表 1.学生表:为简单起见,只考虑了学生id和学生姓名,其中id为主键 2.课程表:为简单起见,只考虑了课程id和课程名称,其中id为主键 3.分数表 分数表有两种解决方案 3.1 第一种为:使用联合主键:student_id 和 course_id 3.2 第二种:不使用

Hibernate映射(二)——多对一关系映射

上篇学习了Hibernate的基本映射,也就是单表映射,很容易就能理解,但是对于关系数据库来说,表之间存在关系是比不可少的,关系数据库中存在的关系是通过主外键建立起来的,反应到Hibernate要如何通过对象表现呢?下面我们就继续学习Hibernate的对象关系映射. 我们先从最常见的多对一和一对多关系开始: 多对一 所谓多对一,在数据库中即在多的一端添加外键关联到一的一端,比如用户(User)和用户所在组(Group)的关系:一个User只属于一个Group,一个Group有多个Group,并

《Hibernate学习笔记九》:多对一和一对多的关联关系

<Hibernate学习笔记九>:多对一和一对多的关联关系 前面介绍了一对一的关联关系在Hibernate应该如何来实现,这篇博文就来介绍下多对一和一对多的关联关系. 多对一和一对多的关联关系在我们的生活中也比较常见,例如,在我们学生时代,一个班级可以有多个学生,而一个学生只能属于一个班级,这就是一个多对一(一对多)的例子: 还有在我们的工作中,一个工作小组可以有多个用户,而一个用户只能属于一个小组,这也是一个多对一(一对多)的关系的例子. 1.多对一的单向关联关系 下面就以一个工作小组可以有