解释:级联,就是对一个对象进行操作的时候,会把他相关联的对象也一并进行相应的操作,相关联的对象意思是指 比如上一篇博客中的一对多关系中,Factory跟Book,Book的实体类中,存在着Classes对象的引用变量,如果保存Classes对象的引用变量有值的话,则该值就是相关联的对象,并且在对Book进行save时,如果保存Classes对象的引用变量有值,那么就会将Classes对象也进行save操作, 这个就是级联的作用。
给一张级联的关系表图
下面举例说明下cascade级联,配置了一个双向一对多的关联关系
Book.java 和 Book.hbm.xml
package com.book.web3;
public class Book {
private int id;
private String name;
private double price;
private int bookCount;
private String author;
private Factory factory;
public int getId(){
return id;
}
public void setId(int id){
this.id = id;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public double getPrice(){
return price;
}
public void setPrice(double price){
this.price = price;
}
public int getBookCount(){
return bookCount;
}
public void setBookCount(int bookCount){
this.bookCount = bookCount;
}
public String getAuthor(){
return author;
}
public void setAuthor(String author){
this.author = author;
}
public Factory getFactory(){
return factory;
}
public void setFactory(Factory factory){
this.factory = factory;
}
}
<hibernate-mapping package="com.book.web3">
<class name="Book" table="tb_books">
<id name="id" column="id" type="int" >
<generator class="assigned" /> <!--generator这个坑,如果指定class为native会导致外部程序设置的主键id无效,且根据数据库自行判断采用自增长式 -->
</id>
<property name="name" type="string">
<column name="name"/>
</property>
<property name="price" type="double" column="price"></property>
<property name="bookCount" type="int" column="bookCount"></property>
<property name="author" type="string" column="author"></property>
<many-to-one name="factory" class="com.book.web3.Factory" cascade="all"> <!--所有情况下均进行关联操作,即save-update和delete。 -->
<column name="factoryid"></column>
</many-to-one>
</class>
</hibernate-mapping>
Factory.java 和 factory.hbm.xml
package com.book.web3;
import java.util.Set;
public class Factory {
private int factoryid;
private String name;
private Set<Book> books;
public int getFactoryid(){
return factoryid;
}
public void setFactoryid(int factoryid){
this.factoryid = factoryid;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public Set<Book> getBooks(){
return books;
}
public void setBooks(Set<Book> books){
this.books = books;
}
}
<hibernate-mapping package="com.book.web3">
<class name="Factory" table="tb_factory">
<id name="factoryid" column="factoryid" type="int" >
<generator class="assigned" /> <!--generator这个坑,如果指定class为native会导致外部程序设置的主键id无效,且根据数据库自行判断采用自增长式 -->
</id>
<property name="name" type="string">
<column name="name"/>
</property>
<set name="books">
<key column="factoryid"></key>
<one-to-many class="com.book.web3.Book"/>
</set>
</class>
</hibernate-mapping>
测试类:
Session session = null;
Book book = new Book();
book.setId(999);
book.setName("英语");
book.setPrice(50);
book.setBookCount(1);
book.setAuthor("美国");
Factory factory = new Factory();
factory.setFactoryid(10);
factory.setName("宾夕法尼亚");
Set<Book> setb = new HashSet<Book>();
setb.add(book);
factory.setBooks(setb);
//这个就是设置相关联的对象
book.setFactory(factory);
try {
session = HibernateUtil.getSession();
//添加数据
session.beginTransaction();
// session.save(factory); //因为在tb_people.hbm.xml设置了级联cascade="save-update"属性
// //只需要保存book,就会将factory也一并保存了;
session.save(book);
session.getTransaction().commit();
结果如图:
当然,这只是在Book这一方设置级联,也可以在Factory这一方设置级联,使的只保存factory,就能将book也保存了。
把factory一方设置级联,修改如下
Book.hbm.xml
<many-to-one name="factory" class="com.book.web3.Factory" > <!--所有情况下均进行关联操作,即save-update和delete。 -->
<column name="factoryid"></column>
</many-to-one>
factory.hbm.xml
<set name="books" cascade="all">
<key column="factoryid"></key>
<one-to-many class="com.book.web3.Book" />
</set>
测试类:
Session session = null;
Book book = new Book();
book.setId(100);
book.setName("世界地图");
book.setPrice(10);
book.setBookCount(1);
book.setAuthor("英国");
Factory factory = new Factory();
factory.setFactoryid(20);
factory.setName("剑桥");
Set<Book> setb = new HashSet<Book>();
setb.add(book);
factory.setBooks(setb);
//这个就是设置相关联的对象
book.setFactory(factory);
session = HibernateUtil.getSession();
//添加数据
session.beginTransaction();
session.save(factory); //只需要保存factory,就会将book也一并保存了
// session.save(book); //只需要保存book,就会将factory也一并保存了; 因为在tb_people.hbm.xml设置了级联cascade="save-update"或者all属性
session.getTransaction().commit();
结果如图:
这里只是把保存对象做一个例子来讲解,级联并不一定就只是级联保存还有很多别的属性,看下面总结
总结:知道了级联的作用,下面来看看级联的属性
cascade关系有以下几种
all: 所有情况下均进行关联操作,即save-update和delete。
none: 所有情况下均不进行关联操作。这是默认值。
save-update: 在执行save/update/saveOrUpdate时进行关联操作。
delete: 在执行delete 时进行关联操作。
all-delete-orphan: 当一个节点在对象图中成为孤儿节点时,删除该节点
我们使用得是save-update,也就是说如果相关联的对象在表中没有记录,则会一起save,如果有,看是否发生改变,会进行update
下面介绍下删除的例子,为了方便,以上的保存和删除全部用了cascade="all"属性
设置Factory为级联时,删除factory直接删除了相关联的book数据
//级联删除cascade=all包含删除
session = HibernateUtil.getSession();
Factory factory = session.get(Factory.class, new Integer("10"));
session.delete(factory);
session.flush();
结果如图:
设置Book为级联时,删除book直接删除了相关联的Factory数据
//级联删除cascade=all包含删除
session = HibernateUtil.getSession();
Book book = session.get(Book.class, new Integer("100"));
session.delete(book);
session.flush();
结果如图: