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();
}
}
而一对一关系映射。一般不写one-to-one,是把one-to-many,many的一方加入unique="true"
Hibernate学习笔记(五) — 多对多关系映射的更多相关文章
- HIbernate学习笔记(六) 关系映射之多对多
六.多对多 - 单向 Ø 一般的设计中,多对多关联映射,需要一个中间表 Ø Hibernate会自动生成中间表 Ø Hibernate使用many-to-ma ...
- Hibernate学习笔记三:对象关系映射(一对一,一对多,多对一,多对多)
如需转载,请说明出处:http://www.cnblogs.com/gudu1/p/6895610.html Hibernate通过关系映射来表示数据库中表与表之间的关系,关系映射可以通过两种方式:配 ...
- Hibernate学习笔记(四)关系映射之一对一关联映射
一. 一对一关联映射 ² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 Ø 主键关联:即让 ...
- hibernate学习(设计多对多 关系 映射)
// package org.crazy.app.domain; import java.util.HashSet; import java.util.Set; import javax.persis ...
- Hibernate框架之双向多对多关系映射
昨天跟大家分享了Hibernate中单向的一对多.单向多对一.双向一对多的映射关系,今天跟大家分享下在Hibernate中双向的多对多的映射关系 这次我们以项目和员工举个栗子,因为大家可以想象得到,在 ...
- 深入浅出Hibernate(二)多对一关系映射
学习Hibernate是为了更方便的操作数据库,在数据库中的关系模型中存在多对一的关系,比方下图所看到的的员工和部门之间的关系,那么这样的关系在Hibernate中怎样映射呢?让我用一个小Demo来具 ...
- Hibernate学习笔记五:反向工程快速开发
转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/6768513.html 一:反向工程 Myeclipse提供由 数据库表 生成 java pojo 和 hib ...
- hibernate学习(设计一对多 关系 映射)
1,配置文件: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-conf ...
- Mybatis学习笔记(五) —— Mapper.xml(输入映射和输出映射)
一.parameterType(输入类型) 1.1 传递简单类型 <!-- 根据用户id查询用户 --> <select id="queryUserById" p ...
随机推荐
- mac链接linux终端,shell脚本发布代码
项目的业务需求:从mac端直接连上linux服务终端,并发布相关的代码 一.使用ssh链接上linux服务端 1.cd ~/.ssh 2.vi config,按照下面的内容配置config文件,然后: ...
- details和summary可以对内容进行折叠
使用<details>和<summary>元素 它可以在body的任意地方使用下面有一个小例子 <!DOCTYPE html> <html lang=&quo ...
- bash, sh, dash 傻傻分不清楚
原文链接,转载请注明出处: http://www.happycxz.com/m/?p=137 常见shell类型 Bourne shell (sh) UNIX 最初使用,且在每种 UNIX 上都可以使 ...
- 六:在线工具网站,让你PC上要装的软件少一半!
记住这几个在线工具网站,让你PC上要装的软件少一半! 一.uzer.me——丰富的云端应用聚合 这个云平台将我们常用的Office系列软件.Adobe家族的系列软件……乃至CAD制图都整合在了云端,随 ...
- Python 3.X 调用多线程C模块,并在C模块中回调python函数的示例
由于最近在做一个C++面向Python的API封装项目,因此需要用到C扩展Python的相关知识.在此进行简要的总结. 此篇示例分为三部分.第一部分展示了如何用C在Windows中进行多线程编程:第二 ...
- C#动态获取鼠标坐标
.Net封装好的方法 int Control.MousePosition.X;int Control.MousePosition.Y; 用API方法 using System.Runtime.Inte ...
- 重构手法之Replace Temp with Query(以查询取代临时变量)
返回总目录 6.4Replace Temp with Query(以查询取代临时变量) 概要 你的程序以一个临时变量保存某一表达式的运算结果. 将这个表达式提炼到一个独立函数中.将这个临时变量的所有引 ...
- [转载] JaCoCo:分析单元测试覆盖率的利器
转载自http://www.ibm.com/developerworks/cn/java/j-lo-jacoco/和http://www.cnblogs.com/chenfengmugu/p/4937 ...
- 重构手法之Introduce Explaining Variable(引用解释性变量)
返回总目录 6.5Introduce Explaining Variable(引用解释性变量) 概要 你有一个复杂的表达式. 将该复杂表达式(或其中一部分)的结果放进一个临时变量,以此变量名称来解释表 ...
- 字符串的缺点以及StringBuilder
字符串的缺点: String 对象是不可改变的.每次使用 System.String 类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间.在需要对字符串执行重复修改的 ...