Hibernate 一对多双向关联Demo
以Classes[班级]和Student[学生]为例的Demo
//Classes.java
public class Classes implements Serializable {
private long cid;
private String cname;
private String cdesc;
private Set<Student> students;
//get和set }
//Student .java
public class Student implements Serializable {
private long sid;
private String sname;
private String sdesc;
private Classes classes;
//get和set
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.test.testDoubl.Classes" >
<id name="cid" type="java.lang.Long" length="5">
<column name="cid"></column>
<generator class="increment"></generator>
</id>
<property name="cname" type="java.lang.String" length="20"></property>
<property name="cdesc" type="java.lang.String" length="50"></property>
<!--
cascade指的是对象对对象的操作
inverse指的是对象对关系的操作
-->
<set name="students" cascade="all">
<key>
<!--
通过classes建立与student之间的联系
-->
<column name="cid"></column>
</key>
<one-to-many class="cn.test.testDoubl.Student"/>
</set>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.test.testDoubl.Student">
<id name="sid" type="java.lang.Long" length="5">
<column name="sid"></column>
<generator class="increment"></generator>
</id>
<property name="sname" type="java.lang.String" length="20"></property>
<property name="sdesc" type="java.lang.String" length="50"></property>
<!--
多对一
注意:在many-to-one中没有inverse属性
对student表的修改本身就是维护外键
-->
<many-to-one name="classes" class="cn.test.testDoubl.Classes" cascade="all">
<!--
外键
描述了通过student建立与classes之间的联系
-->
<column name="cid"></column>
</many-to-one>
</class>
</hibernate-mapping>
总结:
当发生transaction.commit的时候,hibernate内部会检查所有的持久化对象 会对持久化对象做一个更新,因为classes是一个持久化状态的对象,所以hibernate 内部要对classes进行更新,因为在classes.hbm.xml文件中<set name="students" cascade="all" inverse="true"> 意味着在更新classes的时候,要级联操作student,而student是一个临时状态的对象 所以要对student进行保存,在保存student的时候,就把外键更新了。
package cn.test.testDoubl; import java.util.HashSet;
import java.util.Set; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test; public class DoTestDoubl {
private static SessionFactory sessionFactory;
static{
Configuration configuration=new Configuration();
configuration.configure("cn/test/testDoubl/hibernate.cfg.xml");
sessionFactory=configuration.buildSessionFactory();
} /**
* 1、保存班级
* 2、保存学生
* 3、保存班级的时候同时保存学生
* 4、保存班级的时候同时保存学生,并且建立班级和学生之间的关系
* 5、已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
* 6、已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
* 7、已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
* 8、已经存在一个学生,解除该学生和该学生所在班级之间的关系
* 9、解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
* 10、解除该班级和所有的学生之间的关系
* 11、删除班级
* *
* * 解除该班级和所有的学生之间的关系
* * 删除该班级
* *
* 删除班级的同时删除学生
* 12、删除学生
* 同删除班级
*/ //3、保存班级的时候同时保存学生
/*
* Hibernate: select max(cid) from Classes
Hibernate: select max(sid) from Student
Hibernate: insert into Classes (cname, cdesc, cid) values (?, ?, ?)
Hibernate: insert into Student (sname, sdesc, cid, sid) values (?, ?, ?, ?)
Hibernate: update Student set cid=? where sid=?
*/ @Test
public void testSaveClassesandStudent(){ Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction();
Student student=new Student();
student.setSname("1111");
student.setSdesc("111111111111"); Set<Student> set=new HashSet<Student>();
set.add(student); Classes classes=new Classes();
classes.setCname("oo1");
classes.setCdesc("我们都是No。1"); classes.setStudents(set); session.save(classes); transaction.commit();
session.close(); } //4、保存班级的时候同时保存学生,并且建立班级和学生之间的关系
/*
* Hibernate: select max(sid) from Student
Hibernate: select max(cid) from Classes
Hibernate: insert into Classes (cname, cdesc, cid) values (?, ?, ?)
Hibernate: insert into Student (sname, sdesc, cid, sid) values (?, ?, ?, ?)
*/
@Test
public void testSaveClassesandStudent2(){ Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Student student=new Student();
student.setSname("1111");
student.setSdesc("111111111111"); Classes classes=new Classes();
classes.setCname("oo1");
classes.setCdesc("我们都是No。1"); student.setClasses(classes);//通过student来维护classes
//对student的增、删、改本身就是对外键的操作,所以这里不再发出update语句
//一对多,多的一方维护关系,效率比较高 session.save(student); transaction.commit();
session.close(); } //5、已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
/*
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.cdesc as cdesc0_0_ from Classes classes0_ where classes0_.cid=?
Hibernate: select max(sid) from Student
Hibernate: insert into Student (sname, sdesc, cid, sid) values (?, ?, ?, ?)
*/
@Test
public void testSaveStudentToClasses(){
Session session =sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 1L); Student student=new Student();
student.setSname("王尼玛");
student.setSdesc("暴走漫画,就是劲爆");
student.setClasses(classes); session.save(student); transaction.commit();
session.close();
} //6、已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
/*
* Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.sdesc as sdesc1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
Hibernate: select max(cid) from Classes
Hibernate: insert into Classes (cname, cdesc, cid) values (?, ?, ?)
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
*/
@Test
public void testSaveClassesToStudent(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Student student=(Student) session.get(Student.class, 1L); Classes classes=new Classes();
classes.setCname("黑客集训");
classes.setCdesc("里面都是牛人"); student.setClasses(classes); session.save(classes); transaction.commit();
session.close();
} //7、已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
/*
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.cdesc as cdesc0_0_ from Classes classes0_ where classes0_.cid=?
Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.sdesc as sdesc1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
*/
@Test
public void testToRebuild(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 1L);
Student student=(Student) session.get(Student.class, 1L);
student.setClasses(classes);
transaction.commit();
session.close();
} //8、已经存在一个学生,解除该学生和该学生所在班级之间的关系
/*
* Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.sdesc as sdesc1_0_, student0_.cid as cid1_0_ from Student student0_ where student0_.sid=?
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
*/
@Test
public void testToRomove(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Student student=(Student) session.get(Student.class, 1L);
student.setClasses(null); transaction.commit();
session.close();
} //9、解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
/*
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.cdesc as cdesc0_0_ from Classes classes0_ where classes0_.cid=?
Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.sdesc as sdesc1_0_, students0_.cid as cid1_0_ from Student students0_ where students0_.cid=?
Hibernate: select max(sid) from Student
Hibernate: insert into Student (sname, sdesc, cid, sid) values (?, ?, ?, ?)
Hibernate: insert into Student (sname, sdesc, cid, sid) values (?, ?, ?, ?)
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
Hibernate: update Student set sname=?, sdesc=?, cid=? where sid=?
Hibernate: update Student set cid=? where sid=?
Hibernate: update Student set cid=? where sid=?
*/
@Test
public void testremoveAndRebuild(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 2L);
Set<Student> students=classes.getStudents();
for(Student student:students)
{
student.setClasses(null);
} Student student=new Student();
student.setSname("新建1");
student.setSdesc("新建轩辕rtyuio");
Student student2=new Student();
student2.setSname("新建2");
student2.setSdesc("新建轩sdfghyujikol;辕rtyuio"); students.add(student);
students.add(student2); transaction.commit();
session.close();
} //10、解除该班级和所有的学生之间的关系
@Test
public void testRemoveAllStudents(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 2L);
Set<Student> students= classes.getStudents();
for(Student student:students){
student.setClasses(null);
}
transaction.commit();
session.close();
} //11、删除班级
//先解除关系,再删除班级
@Test
public void testDeleteClasses(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 1L);
Set<Student> set=classes.getStudents();
for(Student student:set){
student.setClasses(null);
}
session.delete(classes);
transaction.commit();
session.close();
} //在删除班级的时候,同时删除整个班级的学生 @Test
public void testDeleteClasses2(){
Session session=sessionFactory.openSession();
Transaction transaction=session.beginTransaction(); Classes classes=(Classes) session.get(Classes.class, 2L);
Set<Student> set=classes.getStudents();
for(Student student:set){
student.setClasses(null);
break;
}
//session.delete(classes);
transaction.commit();
session.close();
} }
一对多双向关联例子
Hibernate 一对多双向关联Demo的更多相关文章
- hibernate 一对多双向关联 详解
一.解析: 1. 一对多双向关联也就是说,在加载班级时,能够知道这个班级所有的学生. 同时,在加载学生时,也能够知道这个学生所在的班级. 2.我们知道,一对多关联映射和多对一关联映射是一样的,都是在 ...
- Hibernate 一对多单向关联Demo
以Classes[班级]和Student[学生]为例的Demo Classes .java public class Classes implements Serializable { private ...
- 15.Hibernate一对多双向关联映射+分页
1.创建如下数据库脚本 --创建用户信息表 --编号,用户名,密码,年龄,性别,昵称,手机,地址,管理员,图像地址 create table users ( id ) primary key, use ...
- Hibernate一对多双向关联映射
建立多对一的单向关联关系 Emp.java private Integer empNo //员工编号 private String empName / ...
- Hibernate从入门到精通(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映射,即在一的 ...
- Hibernate(九)一对多双向关联映射
上次的博文Hibernate从入门到精通(八)一对多单向关联映射中,我们讲解了一下一对多单向映射的相关 内容,这次我们讲解一下一对多双向映射的相关内容. 一对多双向关联映射 一对多双向关联映 射,即在 ...
- Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)
一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...
- Hibernate中用注解配置一对多双向关联和多对一单向关联
Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解 ...
- hibernate多对一双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
随机推荐
- QT正则表达式学习(Windows目录禁止九个字符)
exp 正则表达式30分钟入门教程 http://deerchao.net/tutorials/regex/regex.htm 元字符 .*^\d\b\s,当然还有\,还有中括号[] .是一个元字符, ...
- Java this 心得
用类名定义一个变量的时候,定义的应该只是一个引用,外面可以通过这个引用来访问这个类里面的属性和方法,那们类里面是否也应该有一个引用来访问自己的属性和方法纳?呵呵,JAVA提供了一个很好的东西,就是 t ...
- How to add alias on Mac(It's common for most system)
Since these files are hidden you will have to do an ls -a to list them. If you don't have one you ca ...
- 数据结构(二维线段树,差分): NOI2012 魔幻棋盘
貌似想复杂了…… #include <iostream> #include <cstring> #include <cstdio> #define mid ((l+ ...
- 图论(网络流):[CTSC2001]终极情报网
[CTSC2001]终极情报网 [题目描述] 在最后的诺曼底登陆战开始之前,盟军与德军的情报部门围绕着最终的登陆地点展开了一场规模空前的情报战. 这场情报战中,盟军的战术是利用那些潜伏在敌军内部的双重 ...
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1620 Solved: 471 Description 懒得写背景了 ...
- 数学(错排):BZOJ 4517: [Sdoi2016]排列计数
4517: [Sdoi2016]排列计数 Time Limit: 60 Sec Memory Limit: 128 MBSubmit: 693 Solved: 434[Submit][Status ...
- 浅谈层次化的AI架构
原文地址:http://www.aisharing.com/archives/86/comment-page-1 记得在以前的一篇文章中谈到了一种类似于双缓冲的AI结构,最近在整理一些东西的时候,发现 ...
- xp多网卡静态路由设置方法
xp多网卡静态路由设置方法 一.多个IP都在同一网段或VALN.这类情况没什么好说的,在各块网卡的本地连接属性里设置好IP地址.子网掩码和默认网关即可. 二.多个IP属于不同网段或VLAN.这时如果按 ...
- N - Tram - poj1847(简单最短路)
题意:火车从一点开到另一点,轨道上有很多岔路口,每个路口都有好几个方向(火车能够选任意一个方向开),但是 默认的是 第一个指向的方向,所以如果要选择别的方向的话得 进行一次切换操作 ,给定一个起点一个 ...