什么是casecade?
cascade 级联:让操作级联到子实体
- save-update:保存和更新多的一端数据时,一的一端的数据可以一起保存和更新
- none:不级联
- delete:删除级联-不能在多的一端使用
- all:表示所有操作都级联
详解:
1、 cascade时级联操作,使得在操作一端数据时,可以级联操作被关联的另外一端的数据。
2、 在多对一的关系中,多的一端不能操作级联为delete。一般在多的一端设为save-update.
3、 在一对多的关系中,如果一的一端设置为delete时,多的一端不能指明外键为非空。
例子:【Grade和Student类的定义与【7.2】相同】
1.配置文件
Grade.hbm.xml文件:
【<set name="students" cascade="save-update">】
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.siggy.pojo">
<class name="Grade">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<!-- set是 Grade中的集合属性 name属性名称 -->
<set name="students" cascade="save-update">
<!-- key表示外键 column外键列名-->
<key column="grade_id"></key>
<!-- one-to-many 一对多 类Grade 中 students 所表示类型 -->
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
Student.hbm.xml文件:
【<many-to-one name="grade" class="Grade" column="grade_id" cascade="save-update"></many-to-one>】
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.siggy.pojo">
<class name="Student">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name"/>
<property name="age"/>
<!--
cascade 级联:让操作级联到子实体
save-update:保存和更新多的一端数据时,一的一端的数据可以一起保存和更新
none:不级联
delete:删除级联-不能在多的一端使用
all:表示所有操作都级联
-->
<many-to-one name="grade" class="Grade" column="grade_id" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>
2.测试代码【依次执行单元测试@Test】
package cn.siggy.test;
import java.sql.SQLException;
import javax.sql.rowset.serial.SerialException;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
import cn.siggy.pojo.Grade;
import cn.siggy.pojo.Student;
import cn.siggy.util.HibernateUtil;
public class HibernateTest {
@Test
public void testCreateDB(){
Configuration cfg = new Configuration().configure();
SchemaExport se = new SchemaExport(cfg);
//第一个参数 是否生成ddl脚本 第二个参数 是否执行到数据库中
se.create(true, true);
}
@Test
public void testSave() throws HibernateException, SerialException, SQLException{
Session session = null;
Transaction tx = null;
try{
session = HibernateUtil.getSession();
tx = session.beginTransaction();
Grade grade = new Grade();
grade.setName("基础");
Student stu = new Student();
stu.setName("张三疯");
stu.setAge(22);
stu.setGrade(grade);
Student stu1 = new Student();
stu1.setName("老王");
stu1.setAge(23);
stu1.setGrade(grade);
grade.getStudents().add(stu);
grade.getStudents().add(stu1);
//方式一: 保存多的一端,一的一端会级联保存
session.save(stu);
session.save(stu1);
//方式二:保存一的一端,多的一端会级联保存
//session.save(grade);
tx.commit();
}catch (HibernateException e) {
if(tx!=null)
tx.rollback();
e.printStackTrace();
throw e;
}finally{
HibernateUtil.closeSession();
}
}
}
3.测试结果
控制台信息:
详解:
1.在保存Student类信息时,由于casecade=save-update,所以会先保存Student类中Grade属性的信息到grade表中,再保存Student类的信息到student表中
【其中student中的gradeid暂时不保存】:
Hibernate: insert into Grade (name) values (?) Hibernate: insert into Student (name, age, grade_id) values (?, ?, ?) Hibernate: insert into Student (name, age, grade_id) values (?, ?, ?)
2.然后再更新保存grade表的student表的关联【保存gradeid】:
Hibernate: update Student set grade_id=? where id=? Hibernate: update Student set grade_id=? where id=?
数据库表信息: