一对多单向持久化类和映射文件的搭建
1.创建持久化类
1.创建Classes类
package cn.itcast.hibernate0909.onetomany.single;
import java.io.Serializable;
import java.util.Set;
public class Classes implements Serializable{
private Long cid;
private String cname;
public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Set<Student> getStudents() {
return students;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
private String description;
private Set<Student> students;
}
2.创建Student类
package cn.itcast.hibernate0909.onetomany.single;
import java.io.Serializable;
public class Student implements Serializable{
private Long sid;
private String sname;
public Long getSid() {
return sid;
}
public void setSid(Long sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
private String description;
}
2.配置映射文件
1.配置Classes.hbm.xml映射文件
<?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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="cn.itcast.hibernate0909.onetomany.single.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="description" type="java.lang.String" length="100"></property>
<!--
set元素和类中的set集合对应
* 从外键的角度建立classes与student之间的关系
* 从类与类的角度建立classes与student之间的关系
cascade级联
inverse是用来维护关系的
* 要么是一对多的关系
* 要么多对多的关系
* 谁来维护关系
inverse所在的映射文件对应的持久化对象维护关系
默认值是false 表明维护关系
true 表明不维护关系
-->
<set name="students" cascade="save-update">
<!--
key是用来描述外键
column就代表外键的名字
-->
<key>
<column name="cid"></column>
</key>
<!--
classes和哪个对象进行关联
-->
<one-to-many class="cn.itcast.hibernate0909.onetomany.single.Student"/>
</set>
</class>
</hibernate-mapping>
2.配置Student.hbm.xml映射文件
<?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">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="cn.itcast.hibernate0909.onetomany.single.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="description" type="java.lang.String" length="100"></property>
</class>
</hibernate-mapping>
2.配置hibernate.cfg.xml文件
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 是用来描述数据库的连接 -->
<session-factory>
<!--
驱动
-->
<property name="connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!--
url
-->
<property name="connection.url">
jdbc:mysql://localhost:3306/hibernate0909
</property>
<!--
username
-->
<property name="connection.username">root</property>
<!--
password
-->
<property name="connection.password">123</property>
<!--
hibernate针对建表的操作
update 如果有表,检查表的结构,如果没有则创建
create-drop 启动hibernate创建表,结束hibernate删除表
create 每次启动都重新创建表
validate 每次启动都检查表的结构
-->
<property name="hbm2ddl.auto">update</property>
<property name="show_sql">true</property>
<mapping
resource="cn/itcast/hibernate0909/onetomany/single/Classes.hbm.xml" />
<mapping
resource="cn/itcast/hibernate0909/onetomany/single/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
一对多单向关联练习
1.保存班级练习
junit测试结果:
2.保存学生练习
junit测试结果:
说明:这个操作只能插入一student对象,但是在student表中,外键任然为null
3.保存班级的时候同时保存学生
junit测试结果:
4. 在保存班级的同时,级联保存学生
junit测试结果:
5.保存班级的时候同时保存学生,并且建立班级和学生之间的关系
junit测试结果:
6.已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
junit测试结果:
7.已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
junit测试结果:
8.已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
junit测试结果:
9.已经存在一个学生,解除该学生和该学生所在班级之间的关系
junit测试结果:
10. 解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
修改数据库表之前的数据:
junit测试结果:
11.解除该班级和所有的学生之间的关系
junit测试结果:
12. 删除班级
修改数据库表之前的数据:
junit测试结果:
13.删除班级,同时删除学生
修改映射文件:
修改数据库表之前的数据:
junit测试结果:
全部源码
package cn.itcast.hibernate0909.onetomany.single;
import java.util.HashSet;
import java.util.List;
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;
/**
* 1、保存班级
* 2、保存学生
* 3、保存班级的时候同时保存学生
* 4、保存班级的时候同时保存学生,并且建立班级和学生之间的关系
* 5、已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
* 6、已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
* 7、已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
* 8、已经存在一个学生,解除该学生和该学生所在班级之间的关系
* 9、解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
* 10、解除该班级和所有的学生之间的关系
* 11、删除班级
* *
* * 解除该班级和所有的学生之间的关系
* * 删除该班级
* *
* 删除班级的同时删除学生
* 12、删除学生
* 同删除班级
* @author Administrator
*
*/
public class OneToManyTest {
private static SessionFactory sessionFactory;
static{
Configuration configuration = new Configuration();
configuration.configure("cn/itcast/hibernate0909/onetomany/single/hibernate.cfg.xml");
sessionFactory = configuration.buildSessionFactory();
}
/**
* 1、保存班级
*/
@Test
public void testSaveClasses(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = new Classes();
classes.setCname("0909java极品就业班");
classes.setDescription("java学得就是好");
session.save(classes);
transaction.commit();
session.close();
}
/**
* 2、保存学生
*
* 这个操作只能插入一student对象,但是在student表中,外键任然为null
*/
@Test
public void testSaveStudent(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("班长");
student.setDescription("有班秘");
session.save(student);
transaction.commit();
session.close();
}
/**
* 保存班级的时候同时保存学生
*/
@Test
public void testSaveClassAndStudent(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("班秘");
student.setDescription("男女不限,女士优先");
session.save(student);
Classes classes = new Classes();
classes.setCname("0909java精品班");
classes.setDescription("还是极品好");
session.save(classes);
transaction.commit();
session.close();
}
/**
* 在保存班级的同时,级联保存学生
* Hibernate: select max(cid) from Classes
Hibernate: select max(sid) from Student
Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
Hibernate: update Student set cid=? where sid=?
*/
@Test
public void testSaveClass_Cascade_Student(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("菜肉");
student.setDescription("男士");
Set<Student> students = new HashSet<Student>();
students.add(student);
Classes classes = new Classes();
classes.setCname("极品班级");
classes.setDescription("还是极品好");
classes.setStudents(students);
session.save(classes);
transaction.commit();
session.close();
}
/**
* 保存班级的时候同时保存学生,并且建立班级和学生之间的关系
* 在classes.hbm.xml文件中
* <set name="students" cascade="save-update">
* inverse的值为默认或者false,才能让classes维护student的关系
*/
@Test
public void testSaveClassesAndStudent_R(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("某同学");
student.setDescription("高富帅");
Set<Student> students = new HashSet<Student>();
students.add(student);
Classes classes = new Classes();
classes.setCname("重点班");
classes.setDescription("还是重点好");
classes.setStudents(students);
session.save(classes);
transaction.commit();
session.close();
}
/**
* 已经存在一个班级,新建一个学生,并且建立该学生和该班级之间的关系
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_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_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
classes.getStudents()的时候发出的
Hibernate: select max(sid) from Student
Hibernate: insert into Student (sname, description, sid) values (?, ?, ?)
Hibernate: update Student set cid=? where sid=?
建立关系
*/
@Test
public void testSaveStudent_R(){
/**
* 1、查询班级
* 2、新建学生
* 3、建立关系
*/
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = new Student();
student.setSname("小明同学");
student.setDescription("昨天刚刚来");
Classes classes = (Classes)session.get(Classes.class, 1L);
//建立班级和学生之间的关系
classes.getStudents().add(student);
//classes.setStudents(students) 把班级中的学生重新更新了
transaction.commit();
session.close();
}
/**
* 已经存在一个学生,新建一个班级,并且建立该学生和该班级之间的关系
* Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
Hibernate: select max(cid) from Classes
Hibernate: insert into Classes (cname, description, cid) values (?, ?, ?)
Hibernate: update Student set cid=? where sid=?
*/
@Test
public void testSaveClasses_R(){
/**
* 1、查找学生
* 2、新建班级
* 3、建立关系
*/
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Student student = (Student)session.get(Student.class, 2L);
Classes classes = new Classes();
classes.setCname("科学班");
classes.setDescription("很科学");
Set<Student> students = new HashSet<Student>();
students.add(student);
classes.setStudents(students);
session.save(classes);
transaction.commit();
session.close();
}
/**
* 说明:
* 当Classes.hbm.xml映射文件中:
* <set name="students" cascade="save-update">
* 当session.save/update classes时,隐式操作的对象是student,
* 对student决定save操作还是update操作,主要的判断依据是student中sid值在数据库中有没有对应的值
*/
/**
* 已经存在一个学生,已经存在一个班级,解除该学生和原来班级之间的关系,建立该学生和新班级之间的关系
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_0_ from Classes classes0_ where classes0_.cid=?
Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_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_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
Hibernate: select students0_.cid as cid0_1_, students0_.sid as sid1_, students0_.sid as sid1_0_, students0_.sname as sname1_0_, students0_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
Hibernate: update Student set cid=null where cid=? 解除关系
Hibernate: update Student set cid=? where sid=? 建立关系
只需要再重新建立关系即可
*/
@Test
public void testRealse_Rebuild(){
/**
* 1、查找班级
* 2、查找学生
* 3、解除关系
* 4、建立关系
*/
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//Classes classes = (Classes)session.get(Classes.class, 5L);
Student student = (Student)session.get(Student.class, 4L);
Classes classes2 = (Classes)session.get(Classes.class, 5L);
//classes.getStudents().remove(student);//解除关系
classes2.getStudents().add(student);//建立关系
transaction.commit();
session.close();
}
/**
* 已经存在一个学生,解除该学生和该学生所在班级之间的关系
* Hibernate: select student0_.sid as sid1_0_, student0_.sname as sname1_0_, student0_.description as descript3_1_0_ from Student student0_ where student0_.sid=?
Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_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_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
Hibernate: update Student set cid=null where cid=?
解除关系的语句
*/
@Test
public void testRealse_R(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
/**
* 1、查询该学生
* 2、查询该班级
* 3、解除关系
*/
Student student = (Student)session.get(Student.class, 5L);
Classes classes = (Classes)session.get(Classes.class, 1L);
classes.getStudents().remove(student);
transaction.commit();
session.close();
}
/**
* 解除该班级和所有的学生之间的关系,再重新建立该班级和一些新的学员之间的关系
*/
@Test
public void testRealseAll_Rebuild_R(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = (Classes)session.get(Classes.class, 5L);
List<Student> students = session.createQuery("from Student where sid in(3,4,5)").list();
//重新建立班级和学生之间的关系
classes.setStudents(new HashSet<Student>(students));
transaction.commit();
session.close();
}
/**
* 解除该班级和所有的学生之间的关系
*/
@Test
public void testRealseAll_R(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = (Classes)session.get(Classes.class,5L);
classes.setStudents(null);
transaction.commit();
session.close();
}
/**
* 删除班级
* 1、解除该班级和所有的学生之间的关系
* 如果班级具体维护关系的能力,hibernate内部自动实现
* 2、删除班级
*/
@Test
public void testDeleteClasses(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = (Classes)session.get(Classes.class, 1L);
session.delete(classes);
transaction.commit();
session.close();
}
/**
* 删除班级,同时删除学生
* Hibernate: select classes0_.cid as cid0_0_, classes0_.cname as cname0_0_, classes0_.description as descript3_0_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_.description as descript3_1_0_ from Student students0_ where students0_.cid=?
Hibernate: update Student set cid=null where cid=?
解除班级和学生之间的关系
Hibernate: delete from Student where sid=?
Hibernate: delete from Classes where cid=?
*/
@Test
public void testDeleteClasses_Cascade(){
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Classes classes = (Classes)session.get(Classes.class, 5L);
session.delete(classes);
transaction.commit();
session.close();
}
/**
* 总结:
* 1、在整个例子中,班级负责维护关系,只要班级维护关系就会发出update语句
* 2、解除关系就是相对应的外键设置为null
* 3、改变关系就是相对应的外键从一个值变成另外一个值
* 4、在代码中的体现:
* classes.setStudents(); 重新建立关系
* classes.getStudents().remove; 解除关系
* classes.setStudents(null); 解除所有的关系
* classes.getStudents().add() 在原有的关系的基础上再建立关系
*/
}
总结
1、在整个例子中,班级负责维护关系,只要班级维护关系就会发出update语句
2、解除关系就是相对应的外键设置为null
3、改变关系就是相对应的外键从一个值变成另外一个值
4、在代码中的体现:
classes.setStudents(); 重新建立关系
classes.getStudents().remove; 解除关系
classes.setStudents(null); 解除所有的关系
classes.getStudents().add() 在原有的关系的基础上再建立关系

本文详细介绍了一对多单向持久化的实现过程,包括持久化类的创建、映射文件的配置以及通过JUnit测试验证不同场景下的数据操作。
5805

被折叠的 条评论
为什么被折叠?



