在上一篇Hibernate总结(一)简单总结了一级缓存,快照,增删改查的简单使用,这一篇总结两张表的级联操作。

级联涉及到三种情况,many-many,1-many,many-1。

  • 首先是1-many,many-1情况,所以先设置一个情景:客户与订单的关系
//因为太占版面缘故,没有列出get()/set()方法
public class Customer {
private Integer id;
private String name;
private Set<Order> orders = new HashSet<Order>();//1对多
}
public class Order {
private Integer id;
private String name;
private Customer customer;//多对1
}

接下来是hibernate.cfg.xml与两个实体类的配置文件Order.hbm.xml与Customer.hbm.xml,第一个不多说,主要是映射文件的配置

//Customer.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Customer" table="t_customer">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 一对多关系 -->
<!--
       inverse:true 不维护关系,交给拥有外键一方维护
       cascade:save-update(级联保存与级联更新),当然还有其它选项,delete(级联删除),all(级联保存,更新,删除),none(默认没有级联)
   -->
<set name="orders" inverse="true" cascade="save-update">
<key column="cid"></key> <!-- 在Order表中的外键的名字-->
<one-to-many class="Order"/>
</set>
</class>
</hibernate-mapping>
//Order.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Order" table="t_order">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对一关系 -->
<!-- 含有外键一方维护关系 -->
<many-to-one name="customer" column="cid" class="Customer"></many-to-one>
</class>
</hibernate-mapping>

一切准备就绪,开始级联的代码:

因为代码中大量使用了得到连接,关闭连接操作,所以我使用了模板设计模式,在我的文章《Hibernate-模板模式》有讲解

    /**
* 级联保存:
* 1.inverse="true",维护关系,最好只有一方维护,而且是拥有外键一方维护
* 2.cascade="save-update",级联保存与级联更新
*/
@Test
public void test0() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Customer c=new Customer();
c.setName("King");
Order o1=new Order();
o1.setName("炒面");
Order o2=new Order();
o2.setName("肉"); o1.setCustomer(c);//由拥有外键一方维护关系
o2.setCustomer(c); s.save(c);
s.save(o1);
s.save(o2);//这样框架只执行了3条SQL语句
}
}.execute();
}
    /**
* 级联删除:
* 1.inverse="false"为默认处理方式:把客户的订单的外键修改为null,然后再删除客户
* 2.inverse="true"若客户不处理,会出错
*/
@Test
public void test1() {
new SessionTemplate(){
@Override
public void fun(Session s) {
         //这是没有使用级联删除的情况,这时cascade为save-update
Customer c=(Customer) s.get(Customer.class, 3);
for(Order o:c.getOrders()){
s.delete(o);
}
s.delete(c);//此时,inverse="true",所以前面删除了所有客户的订单才能删除客户          //更改配置文件,cascade为delete,这时就是级联删除
                Customer c=(Customer) s.get(Customer.class, 3);
s.delete(c);//这时不需要手动删除订单了
            }
}.execute();
}
    /**
* 级联更新
   * cascade为save-update 
*/
@Test
public void test2() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Customer c=(Customer) s.get(Customer.class, 2);
for(Order o:c.getOrders()){
o.setName("羊杂汤");//持久态,不需要更新
}
}
}.execute();
}

查询涉及到了加载策略,所以很复杂,所以将在写在下一篇中。

  • 接下来说many-many的情况,还是先设置一个情景:学生与课程的关系
public class Student {
private Integer id;
private String name;
private Set<Course> courses=new HashSet<>();//多对多
}
public class Course {
private Integer id;
private String name;
private Set<Student> students=new HashSet<>();//多对多
}

接下来是两个实体类与数据库表的映射文件:

//Student.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Student" table="t_student">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对多关系,在多对多中,需要双方都设置存储关系的表名 -->
<set name="courses" cascade="save-update" table="t_selectcourse">
<key column="sid"></key>
<many-to-many class="Course" column="cid"></many-to-many>
</set>
</class>
</hibernate-mapping>
//Course.hbm.xml
<hibernate-mapping package="king.domain">
<class name="Course" table="t_course">
<id name="id" column="id">
<generator class="native"></generator>
</id>
<property name="name" column="name"></property>
<!-- 多对多关系 -->
<!-- 维护权反转给对方 -->
<set name="students" inverse="true" table="t_selectcourse">
<key column="cid"></key>
<many-to-many class="Student" column="sid"></many-to-many>
</set>
</class>
</hibernate-mapping>

一切准备继续,开始代码工作:

    /**
* 多对多
* 级联保存:
   * 本来想也写上级联删除与级联更新,但是发现写的代码和我想要实现的结果不同,故没有贴出代码,额...我的意思就是我也不会...挺尴尬...
*/
@Test
public void test0() {
new SessionTemplate(){
@Override
public void fun(Session s) {
Student s1=new Student();
s1.setName("King"); Course c1=new Course();
c1.setName("数学");
Course c2=new Course();
c2.setName("英语"); s1.getCourses().add(c1);//由学生维护关系
s1.getCourses().add(c2);//由学生维护关系 s.save(s1);
}
}.execute();
}

增删改查,现在就差“查”没有写出,我将在下一篇总结中写出Hibernate的关于查询的加载策略。

Hibernate总结(二)的更多相关文章

  1. Hibernate实例二

    Hibernate实例二 一.测试openSession方法和getCurrentSession方法 hebernate中可以通过上述两种方法获取session对象以对数据库进行操作,下面的代码以及注 ...

  2. hibernate学习二(HelloWorld)

    一.建立hibernate配置文件 在工程Hibernate_01_HelloWorld下的src上建立hibernate.cfg.xml,打开hibernate-release-4.3.11.Fin ...

  3. hibernate(二)annotation第一个示例

    一.在数据库中创建teacher表(数据库hibernate) create table teache( id int auto_increment primary key, name ), titl ...

  4. hibernate学习(二)

    hibernate 单向一对多映射 一.数据表设计 数据库名:hibernate5 数据表: ①表名:CUSTOMERS 字段: CUSTOMER_ID  CUSTOMER_NAME ②表名:ORDE ...

  5. Hibernate(二)之Hibernate-api详解

    一.Hibernate体系结构 二.Hibernate-api详解 2.1.Configuration配置对象 Configuration是用来加载配置文件的 我们Hibernate中主要有两个配置文 ...

  6. Hibernate(二)

    1.1Hibernate的持久化类状态 1.1.1Hibernate的持久化类状态 持久化类:就是一个实体类和数据库表建立了映射关系. Hibernate为了方便的管理持久化类,将持久化类分成了三种状 ...

  7. Hibernate学习(二)关系映射----基于外键的单向一对一

    事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似.只需要将原来的many-to-one元素增加unique="true"属性, ...

  8. Java框架之Hibernate(二)

    本文主要介绍: 1 Criteria 接口 2 用 myeclipse 反向生成 3 hibernate  主键生成策略 4 多对一 5 一对多 6 使用List 集合的一对多 7 多对多 一.Cri ...

  9. SSH框架之hibernate《二》

    Hibernate第二天     一.hibernate的持久化类和对象标识符         1.1持久化类的编写规范             1.1.1什么是持久化类:               ...

  10. JAVA框架:hibernate(二)

    一.事务操作. 代码: @Test public void tr_Up(){ Session session=hibernateUtils.getSession(); Transaction tran ...

随机推荐

  1. lua随机数的问题

    在看 lua 的 math.random 函数的时候发现一个问题,就是在没有重新设置随机种子的时候, random 返回的前几个随机数并不是那么特别随机,尤其当随机范围很小的时候,比如 100 左右的 ...

  2. WPF入门教程系列四——Dispatcher介绍

    一.Dispatcher介绍 微软在WPF引入了Dispatcher,那么这个Dispatcher的主要作用是什么呢? 不管是WinForm应用程序还是WPF应用程序,实际上都是一个进程,一个进程可以 ...

  3. dubbo+zookeeper简单环境搭建

    dubbo+zoopeeper例子 [TOC] 标签(空格分隔): 分布式 dubbo dubbo相关 dubbo是目前国内比较流行的一种分布式服务治理方案.还有一种就是esb了.一般采用的是基于Ap ...

  4. LigerUI学习使用

    LigerUI有如下主要特点: 使用简单,轻量级 控件实用性强,功能覆盖面大,可以解决大部分企业信息应用的设计场景 快速开发,使用LigerUI可以比传统开发减少极大的代码量 易扩展,包括默认参数.表 ...

  5. 编写Shader时的一些性能考虑

    编写shader时的一些建议:1.只计算需要计算的东西:2.通常,需要渲染的像素比顶点数多,而顶点数又比物体数多很多.所以如果可以,尽量将运算从PS移到VS,或直接通过script来设置某些固定值:3 ...

  6. Razor基本语法

    前言: Razor引擎的核心是识别@符号及尖括号:    1.<...></...>    2.<.../>    [之所以说是"尖括号"而非& ...

  7. Java多线程系列--“JUC原子类”03之 AtomicLongArray原子类

    概要 AtomicIntegerArray, AtomicLongArray, AtomicReferenceArray这3个数组类型的原子类的原理和用法相似.本章以AtomicLongArray对数 ...

  8. 云计算之路-阿里云上:Web服务器遭遇奇怪的“黑色30秒”问题

    今天下午访问高峰的时候,主站的Web服务器出现奇怪的问题,开始是2台8核8G的云服务器(ECS),后来又加了1台8核8G的云服务器,问题依旧. 而且3台服务器特地使用了不同的配置:1台是禁用了虚拟内存 ...

  9. Nutch源码阅读进程2---Generate

    继之前仓促走完nutch的第一个流程Inject后,再次起航,Debug模式走起,进入第二个预热阶段Generate~~~   上期回顾:Inject主要是将爬取列表中的url转换为指定格式<T ...

  10. Animo.js :一款管理 CSS 动画的强大的小工具

    Animo.js 是一个功能强大的小工具,用于管理 CSS 动画.它的特色功能包括像堆栈动画,创建跨浏览器的模糊,设置动画完成的回调等等.Animo 还包括惊人的 animate.css,为您提供了近 ...