在上一篇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. Atitit apache 和guava的反射工具

    Atitit apache 和guava的反射工具 apache1 Spring的反射工具类 ReflectionUtils1 Guava 反射工具2 apache  34             7 ...

  2. salesforce 零基础学习(十九)Permission sets 讲解及设置

    Permission sets以及Profile是常见的设置访问权限的方式. Profile规则为'who see what'.通过Profile可以将一类的用户设置相同的访问权限.对于有着相同Pro ...

  3. java基础,继承类题目:编写一个Java应用程序,该程序包括3个类:Monkey类、People类和主类 E

    21.编写一个Java应用程序,该程序包括3个类:Monkey类.People类和主类 E.要求: (1) Monkey类中有个构造方法:Monkey (String s),并且有个public vo ...

  4. Sublime快速上手

    在当前的互联网时代,任何程序语言和相关技术都只是实现互联网应用的一种手段,这也就造成了大量的互联网工程师长期与不同的语言.技术.系统环境.IDE等打交道.因此一个相对统一方便的IDE对于程序员来说显得 ...

  5. JavaScript与有限状态机

    有限状态机(Finite-state machine)是一个非常有用的模型,可以模拟世界上大部分事物. 简单说,它有三个特征: * 状态总数(state)是有限的. * 任一时刻,只处在一种状态之中. ...

  6. 分享一个 C# Winfrom 下的 OutlookBar 控件的使用

    最近在上网的时候,发现了这个C# 下的 OutlookBar 控件,看了一下感觉还真不错,特此记录一下. using System; using System.Drawing; using Syste ...

  7. ZZUOJ1196: 单调数

    /* 注意的事项:是输出小于 10^n的正整数的个数哦!开始的时候总比样例输出多一个数, 纠结了好久,原来是 0加了进去了! dpI[n][m]表示的是第n位添加数字m(0....9)的构成单调递增数 ...

  8. Kruskal算法(三)之 Java详解

    前面分别通过C和C++实现了克鲁斯卡尔,本文介绍克鲁斯卡尔的Java实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解 4. 克鲁斯卡尔算法分析 5. 克鲁斯卡尔算法的 ...

  9. Android调用手机摄像头使用MediaRecorder录像并播放

    最近在项目开发中需要调用系统的摄像头录像并播放. 在开发中遇到了两个问题,记录下: (1)开发过程中出现摄像头占用,启动失败,报错.但是我已经在onDestory()中关闭了资源. 报错原因:打开程序 ...

  10. PHP函数处理函数实例详解

    1. call_user_func和call_user_func_array:  以上两个函数以不同的参数形式调用回调函数.见如下示例: <?php class AnotherTestClass ...