创建JavaBean

一方: Customer

private long cust_id;
private String cust_name;
private long cust_user_id;
private long cust_create_id;
private String cust_source;
private String cust_industry;
private String cust_level;
private String cust_linkman;
private String cust_phone;
private String cust_mobile; //存储联系人的集合,该属性并不会出现在数据库中
private Set<LinkMan> linkmans = new HashSet<LinkMan>(); //--加上所有的get/set方法 无参构造函数

多方: LinkMan

private long lkm_id;
private String lkm_name;
private String lkm_gender;
private String lkm_phone;
private String lkm_mobile;
private String lkm_email;
private String lkm_qq;
private String lkm_position;
private String lkm_memo; //外键对象
private Customer customer; //--加上所有的get/set方法 无参构造函数

配置多方的映射文件

<!-- 先配置多方
name:当前JavaBean中的属性
class:属性的全路径
column:外键的字段
-->
<many-to-one name="customer" class="com.hibernateday3.domain.Customer" column="lkm_cust_id"/>

配置一方的映射文件

 <!-- 后配置一方
set->name:表示集合的名称
-->
<set name="linkmans">
<!-- 外键的字段与路径 -->
<key column="lkm_cust_id"/>
<one-to-many class="com.hibernateday3.domain.LinkMan"/>
</set>

将映射文件配置到核心文件

<!-- 映射配置文件 -->
<mapping resource="com/hibernateday3/domain/Customer.hbm.xml"/>
<mapping resource="com/hibernateday3/domain/Linkman.hbm.xml"/>

测试:

1.测试双向关联方式

@Test
public void m01(){
Session session = HibernateUtils.openSession();
Transaction tr = session.beginTransaction(); Customer c1 = new Customer();
c1.setCust_name("客户1");
LinkMan l1 = new LinkMan();
l1.setLkm_name("联系人1");
LinkMan l2 = new LinkMan();
l2.setLkm_name("联系人2"); c1.getLinkmans().add(l1);
c1.getLinkmans().add(l2); //------保存数据
//双向关联保存
session.save(c1);
session.save(l1);
session.save(l2); //------提交事务释放资源
tr.commit();
session.close();
}

2.单向的关联,如果不配置级联保存,程序出现异常

//------保存数据
//双向关联保存 session.save(c1); //------提交事务释放资源
警告:org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.hibernateday3.domain.LinkMan

如果想完成只保存一方的数据,并且把相关联的数据都保存到数据库中,那么需要配置级联!!

级联保存是具有方向性的

3.测试级联保存:保存客户,级联联系人

---在一方映射文件加入cascade属性

<set name="linkmans" cascade="save-update">
<!-- 外键的字段与路径 -->
<key column="lkm_cust_id"/>
<one-to-many class="com.hibernateday3.domain.LinkMan" />
</set>
//------保存数据
//双向关联保存 session.save(c1); //------提交事务释放资源

运行成功。。

4.测试级联保存:保存联系人,级联客户

---在多方映射文件加入cascade属性

<many-to-one name="customer" class="com.hibernateday3.domain.Customer" column="lkm_cust_id" cascade="save-update"/>
//------保存数据
//双向关联保存 session.save(l1);
session.save(l2); //------提交事务释放资源

运行成功。。

5.测试级联保存


//------保存数据
//双向关联保存
l1.setCustomer(c1);
c1.getLinkmans().add(l2);
session.save(l1);
//------提交事务释放资源

运行成功。。

6.测试:删除一方,一方下有2个联系人

public void m06(){
Session session = HibernateUtils.openSession();
Transaction tr = session.beginTransaction(); //------保存数据
//双向关联保存 Customer c1 = session.get(Customer.class, 1L);
session.delete(c1); //------提交事务释放资源
tr.commit();
session.close();
}

能够成功 并不会因为一方是多方的外键二不能删除
Hibernate先让多方删除外键 再删除一方

7.测试级联删除,删除客户,级联删除客户下的联系人

在一方映射文件下添加属性

<set name="linkmans" cascade="save-update,delete">
<!-- 外键的字段与路径 -->
<key column="lkm_cust_id"/>
<one-to-many class="com.hibernateday3.domain.LinkMan" />
</set>
//------保存数据
//双向关联保存 Customer c1 = session.get(Customer.class, 1L);
session.delete(c1); //------提交事务释放资源

删除c1  c1对应的l1,l2都被删除了

8.删除联系人,级联删除客户

在多方映射文件下添加属性

    <many-to-one name="customer" class="com.hibernateday3.domain.Customer" column="lkm_cust_id" cascade="save-update,delete"/>
//------保存数据
//双向关联保存 LinkMan l1 = session.get(LinkMan.class,1L ); session.delete(l1); //------提交事务释放资源

如果一方下的cascade的delete属性依然存在,所有的数据都被删除

9.解除关系,从一方集合中移除多方数据

// 先获取到客户
Customer c1 = session.get(Customer.class, 1L);
LinkMan l1 = session.get(LinkMan.class, 1L);
// 解除
c1.getLinkmans().remove(l1);

多方的外键被解除设为null

如果cascade属性为delete-orphan 解除关系 ,多方记录将被删除(孤儿关系)

1. 取值如下
* none -- 不使用级联
* save-update -- 级联保存或更新
* delete -- 级联删除
* delete-orphan -- 孤儿删除.(注意:只能应用在一对多关系)
* all -- 除了delete-orphan的所有情况.(包含save-update delete)
* all-delete-orphan -- 包含了delete-orphan的所有情况.(包含save-update delete delete-orphan) 2. 孤儿删除(孤子删除),只有在一对多的环境下才有孤儿删除
* 在一对多的关系中,可以将一的一方认为是父方.将多的一方认为是子方.孤儿删除:在解除了父子关系的时候.将子方记录就直接删除。
* <many-to-one cascade="delete-orphan" />

放弃外键维护

1. 先测试双方都维护外键的时候,会产生多余的SQL语句。
* 想修改客户和联系人的关系,进行双向关联,双方都会维护外键,会产生多余的SQL语句。
/**
* 放弃外键的维护
* 需求:让c1联系人l1属于c2
*/
@Test
public void m11(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); Customer c2 = session.get(Customer.class,2L);
LinkMan l1 = session.get(LinkMan.class, 1L); c2.getLinkmans().add(l1);
l1.setCustomer(c2); tr.commit();
}


    * 产生的原因:session的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的SQL语句。

2. 如果不想产生多余的SQL语句,那么需要一方来放弃外键的维护!
* 在<set>标签上配置一个inverse=”true”.true:放弃.false:不放弃.默认值是false
* <inverse="true">
<set name="linkmans" inverse="true">
<!-- 外键的字段与路径 -->
<key column="lkm_cust_id"/>
<one-to-many class="com.hibernateday3.domain.LinkMan" />
</set>
/**
* 放弃外键的维护
* 需求:让c1联系人l1属于c2
*/
@Test
public void m11(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); Customer c2 = session.get(Customer.class,2L);
LinkMan l1 = session.get(LinkMan.class, 1L); c2.getLinkmans().add(l1);
l1.setCustomer(c2); tr.commit();
}


cascade和inverse的区别
1. cascade用来级联操作(保存、修改和删除)---配置在多方
2. inverse用来维护外键的  ----配置在一方

11.Hibernate一对多关系的更多相关文章

  1. 菜鸟学习Hibernate——一对多关系映射

    Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创 ...

  2. hibernate一对多关系配置

    一.     表信息 公司表 cId cName cAdress Null Null Null 表t_company 员工表 sId sName sAge cId Null Null Null Nul ...

  3. Hibernate一对多关系操作

    1.创建两个实体类. 一个实体类是商品类,另一个实体类是商品的分类类. 在一对多关系的两个实体中,在编写实体类时必须要遵循以下规则: (1)在一的那一方的实体中,必须要有一个私有的多那一方的实体对象属 ...

  4. hibernate 一对多关系中的孤儿属性

    @OneToMany(targetEntity = BenefitType.class, mappedBy = "sitePerson",cascade = CascadeType ...

  5. hibernate一对多关系映射(自身关联)

    示例:一个类别(Category)下面有多个子类别,多个子类别属于同一个父类别. public class Category  { private Integer id; private String ...

  6. hibernate一对多关系 在一方查询会获得重复数据,重复数量就是多端数据数量用@Fetch(FetchMode.SUBSELECT)解决

    先来看数据表 版块表只有两个数据 板块1是推荐,下边没有子栏目 板块2下边有14个子栏目 在1的一端来查询,发现结果有16条 也就是板块1+版块2+版块2和他的14个子集都列出来了,这明显不对 板块对 ...

  7. hibernate中一对多关系中的inverse,cascade属性

    举例说明: 一对多关系的两张表:boy.girl(一个男孩可以多个女朋友) boy表结构 Field   Type        ------  -----------  name    varcha ...

  8. 【Java EE 学习 45】【Hibernate学习第二天】【对象的三种状态】【一对多关系的操作】

    一.对象的三种状态. 1.对象有三种状态:持久化状态.临时状态.脱管状态(游离状态) 2.Session的特定方法能使得一个对象从一个状态转换到另外一个状态. 3.三种状态的说明 (1)临时状态:临时 ...

  9. hibernate学习(5)——一对多关系表达

    一对多实现 1. 实现类 package com.alice.hibernate02.vo; import java.util.HashSet; import java.util.Set; publi ...

随机推荐

  1. NOI2019网络同步赛总结

    先说说分数:\(100+20+0+100+0+0=220\) 我果然还是个大蒟蒻-- Day1 比赛之前还在回顾着<灵笼>,时间一到就立刻进入比赛. 快速地浏览了一遍题目,然后开始刚T1. ...

  2. Open CV 环境配置

    { //https://github.com/zhmmmm/ANYTOOL-2.0.0.0.2Version/tree/master/OpenCVProject } /* //各个版本下载 https ...

  3. [Codeplus 4月赛]最短路

    题意:理论上是给定一张完全图,有边权,在给一些单向边求最短路. 思路: 我充分体会到了我图论的菜. 理论上建图肯定是不能\(n^2\)的,考虑如何优化呢? 将边权异或值二进制替换,最后一遍最短路就行, ...

  4. ajax跨域获取网站json数据

    由于自己的公司的项目需要调用视频地址 1:当为链接时:直接在播放器用数据库查找的地址 2:当为外部链接时:直接用window.location.href('数据库查找的地址') 3:当为H5链接时:使 ...

  5. JAVA 设计的七大原则

    一.开闭原则 开闭原则(Open-Closed Principle, OCP)是指一个软件实体如类.模块和函数应该对 扩展开放,对修改关闭. 所谓的开闭,也正是对扩展和修改两个行为的一个原则.强调 的 ...

  6. jQuery WeUI

    jQuery WeUI jQuery WeUI 是专为微信公众账号开发而设计的一个简洁而强大的UI库,包含全部WeUI官方的CSS组件,并且额外提供了大量的拓展组件,丰富的组件库可以极大减少前端开发时 ...

  7. 安装MySql社区版(35-3)

    1,https://dev.mysql.com/ --------------------------------------------------------------------------- ...

  8. python爬取凤凰网站的新闻,及其链接地址,来源,时间和内容,用selenium自动化和requests处理数据

    有写规则需要自己定义判断. import requests from selenium import webdriver import time def grasp(urlT): driver = w ...

  9. CDH断电后 hbase出现spilt块不完整问题

    从错误看起来是regionspilt时候断电了,导致hbase master启动不起来,因为是测试环境只能删除这些region了,掉一部分数据 删除hbase下spilt块,删除zK里面的habse ...

  10. C++返回引用的需求

    1.重载+=操作符返回*this或者某个参数的引用可以方便链式调用,比如C++流操作就是cout<< a << b << c这样的,就是靠不停返回stream的引用 ...