1. 一对多映射

1.1 JavaWeb 一对多建表原则

  • 多方表的外键指向一方表的主键;

1.2 编写一对多的 JavaBean

// 客户(一方)和联系人(多方)
// 客户(一方) JavaBean
public class Customer{
private Long cust_id;
private String cust_name;
private Long cust_create_id;
... // 关联多方
// Hibernate 框架默认的集合是 Set 集合,该集合必须要自己手动初始化
private Set<Linkman> linkmans = new HashSet<Linkman>(); ......
} // 联系人(多方) JavaBean
public class Linkman{
private Long lkm_id;
private String lkm_name;
private String lkm_gender;
... // 关联一方
// 编写一个对象, 不需要自己 new
private Customer customer; ....
}

1.3 编写一对多的映射配置文件

// Customer.hbm.xml (客户映射配置)
<class name="com.itheima.domain.Customer" table="cst_customer">
<id name="cust_id" column="cust_id">
<generator class="native"/>
</id> <property name="cust_name" column="cust_name"/>
<property name="cust_create_id" column="cust_create_id"/>
... // 关联的配置(一方)
// name 表示集合的名称
<set name="linkmans">
<key column="lkm_cust_id"/> // column 外键的字段
<one-to-many class="com.itheima.domain.Linkman"/>
</set>
</class> // Linkman.hbm.xml (联系人映射配置)
<class name="com.itheima.doamin.Linkman" table="cst_linkman">
<id name="lkm_id" column="lkm_id">
<generator class="native"/>
</id> <property name="lkm_name" column="lkm_name"/>
<property name="lkm_gender" column="lkm_gender"/>
... // 关联的配置(多方)
// name 当前 JavaBean 中的属性
// class 属性的全路径
// column 外键的字段(表)
<many-to-one name="customer" class="com.itheima.domain.Customer" column="lkm_cust_id"/>
</class>

2. 保存客户和联系人的数据

2.1 双向关联的方式保存数据

 public class Demo{
public void fun(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); // 创建客户
Customer c1 = new Customer();
c1.setCust_name("张三"); // 创建联系人
Linkman lk1 = new Linkman();
lk1.setLkm_name("熊大"); Linkman lk2 = new Linkman();
lk2.setLkm_name("熊二"); // 双向关联
c1.getLinkmans().add(lk1);
c1.getLinkmans().add(lk2); lk1.setCustomer(c1);
lk2.setCustomer(c1); session.save(c1);
session.save(lk1);
session.save(lk2); tr.commit();
}
}

2.2 级联保存

  • 级联保存:保存一方,同时可以把关联的对象也保存到数据库中!
  • 级联保存是有方向性的.例如,保存客户时,级联保存联系人;或者,保存联系人时,级联保存客户;
  • 使用 cascade="save-update"
// 保存客户,级联保存联系人
// 需要在客户 Customer.hbm.xml 中配置
<set name="linkmans" cascade="save-update">
<key column="lkm_cust_id"/>
<one-to-many class="com.itheima.domain.Linkman"/>
</set> pulic class Demo{ pulic class fun(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); // 创建客户
Customer c1 = new Customer();
c1.setCust_name("张三"); // 创建联系人
Linkman l1 = new Linkman();
l1.setLkm_name("熊大"); Linkman l2 = new Linkman();
l2.setLkm_name("熊二"); // 单向关联
c1.getLinkmans().add(l1);
c1.getLinkmans().add(l2); l1.setCustomer(c1); // 此处,如果没有,报错.
l2.setCustomer(c1); // 此处,如果没有,报错. // 保存客户
session.save(c1); tr.commit();
}
} // 保存联系人,级联保存客户
// 需要在联系人 Linkman.hbm.xml 中配置
<many-to-one name="customer" class="cn.itheima.domain.Customer"
column="lkm_cust_id" cascade="save-update"/> public class Demo{
public class fun(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); // 创建客户
Customer c1 = new Customer();
c1.setCust_name("张三"); // 创建联系人
Linkman l1 = new Linkman();
l1.setLkm_name("熊大"); Linkman l2 = new Linkman();
l2.setLkm_name("熊二"); l1.setCustomer(c1);
l2.setCustomer(c2); // 保存联系人
session.save(l1);
session.save(l2); tr.commit();
}
}

2.3 级联删除

  • 级联删除也是有方向性的;
// 删除客户时, 删除联系人(一方级联删除多方), 配置 Customer.hbm.xml
<set name="linkmans" cascade="delete">
<key column="lkm_cust_id"/>
<one-to-many class="cn.itheima.domain.Linkman"/>
</set>

2.4 级联的取值和孤儿删除

1. 级联的取值(cascade 的取值)
  • none: 不使用级联;
  • save-update: 级联保存或更新;
  • delete: 级联删除;
  • delete-orphan: 孤儿删除(只能应用在一对多关系);
  • all: 除了 delete-orphan 的所有情况;
  • all-delete-orphan: 包含了 delete-orphan 的所有情况;
2. 孤儿删除
  • 只有在一对多的环境下才有孤儿删除;
  • 在一对多的关系中,可以将一方认为是父方,将多的一方认为是子方;孤儿删除,就是在解除了父子关系的时候,

    将子方记录直接删除;

2.5 让某一方放弃外键的维护,为多对多映射做准备: inverse

  1. 在修改客户和联系人的关系时,进行双向关联,双方都会维护外键,会产生多余的 SQL 语句.

    • 产生的原因: session 的一级缓存中的快照机制,会让双方都更新数据库,产生了多余的 SQL 语句.
  2. 如果不想产生多余的 SQL 语句,那么需要一方来放弃外键的维护, 由多方来维护!
// 放弃外键维护
// Customer.hbm.xml 进行如下配置
<set name="linkman" inverse="true"> // true 表示放弃; 默认值为 false
<key column="lkm_cust_id"/>
<one-to-many class="com.itheima.domain.Linkman"/>
</set>

3. 多对多映射

3.1 多对多建表原则

  • 以用户和角色为例,需要创建三张表: 用户表,角色表,中间表(维护前面两个表的数据);
  • 使用Hibernate 框架,只要编写两个 JavaBean 以及对应的映射配置文件,中间表会自动生成;
  • 多对多映射关系中,必须有一方放弃外键维护;

// 编写用户和角色的 JavaBean
// 用户的 JavaBean
public class User{
private Long user_id;
private String user_name;
private String user_pwd;
... private Set<Role> roles = new HashSet<Role>();
} // 角色的 JavaBean
public class Role{
private Long role_id;
private String role_name;
private String role_desc; private Set<User> users = new HashSet<User>();
} // 编写映射配置文件
// 用户的映射配置文件, User.hbm.xml
<class name="com.itheima.domain.User" table="sys_user">
<id name="user_id" column="user_id">
<generator class="native"/>
</id> <property name="user_name" column="user_name"/>
<property name="user_pwd" column="user_pwd"/> // 配置多对多
// name 表示集合的名称
// table 表示中间表的名称
<set name="roles" table="sys_user_role" inverse="true">
// 当前对象在中间表的外键名称
<key column="user_id"/> // class : 集合中存入的对象,对象的全路径
// column: 集合中对象,在中间表的外键名称
<many-to-many class="com.itheima.domain.Role" column="role_id"/>
</set> </class> // 角色的映射配置文件, Role.hbm.xml
<class name="com.itheima.domain.Role" table="sys_role">
<id name="role_id" column="role_id">
<generator class="native"/>
</id> <property name="role_name" column="role_name"/>
<property name="role_desc" column="role_desc"/> <set name="users" table="sys_user_role">
<key column="role_id"/>
<many-to-many class="com.itheima.domain.User" column="user_id"/>
</set>
</class>

参考资料

Hibernate 中一对多和多对多映射的更多相关文章

  1. Hibernate中一对多和多对一关系

    1.单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时如果只需要获取对应部门信息(user.getdept ...

  2. Hibernate之关联映射(一对多和多对一映射,多对多映射)

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习以下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  3. Hibernate之关联关系映射(一对多和多对一映射,多对多映射)

    ~~~接着之前的Hibernate框架接着学习(上篇面试过后发现真的需要学习一下框架了,不然又被忽悠让去培训.)~~~ 1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1: ...

  4. java web(六):mybatis之一对一、一对多、多对多映射

    前言: 百度百科: MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...

  5. Hibernate中的一对多与多对一映射

    1.需求 一个部门有多个员工;         [一对多] 多个员工,属于一个部门    [多对一] 2.实体Bean设计 Dept: public class Dept { private int ...

  6. Hibernate自身一对多和多对多关系映射

    一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别 ...

  7. hibernate中一对多多对一关系设计的理解

    1.单向多对一和双向多对一的区别? 只需要从一方获取另一方的数据时 就使用单向关联双方都需要获取对方数据时 就使用双向关系 部门--人员 使用人员时如果只需要获取对应部门信息(user.getdept ...

  8. hibernate 2 一对多、多对一 双向映射

    多对一或一对多中,在多的一方维护关系效率高 一:java实体类 1.Classes.java package cn.gs.ly.school.entity; import java.util.Set; ...

  9. Mybatis(四) 高级映射,一对一,一对多,多对多映射

    天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种 ...

随机推荐

  1. 使用sublime模板加快编码效率

    这是使用模板系列的最后一篇了,也是最实用的方法. 前面提到的,插入文件的方法,适合计算机水平一般的初学者:而用TCL脚本的,则适合喜欢自定义各种奇特功能的专业人士. 那么,本次介绍的配置编辑器的方法, ...

  2. eclipse 启动时使用指定的jdk

    -vmD:/DevPrograms/Java/jdk1.5.0_22/bin/javaw.exe-startupplugins/org.eclipse.equinox.launcher_1.1.1.R ...

  3. python学习之pypandoc

    对于程序员来说,文件格式之间的转换是一件非常费劲的事!比如md文件转化为html文件. 于是乎,就有一群牛人搞出了个神器,他就是pandoc. 而python中,对应的第三方模块就是pypandoc. ...

  4. NYOJ 78 圈水池 (入门级凸包)

    题目链接:nyoj 78  单调链凸包小结 题目讲解:本题考查的主要是凸包的用法,算是入门级的吧,当然前提是你接触过,平面几何: AC代码: #include<iostream> #inc ...

  5. 大型跨境电商 JVM 调优经历

    前提: 某大型跨境电商业务发展非常快,线上机器扩容也很频繁,但是对于线上机器的运行情况,特别是jvm内存的情况,一直没有一个统一的标准来给到各个应用服务的owner.经过618大促之后,和运维的同学讨 ...

  6. 数据库设计(四)数据库的规范化(Normalization)

    数据库的规范化 Database Normalization is a technique of organizing the data in the database. Normalization ...

  7. Supervisord常见用法和介绍

    Supervisord是用Python实现的一款非常实用的进程管理工具.supervisord会帮你把管理的应用程序转成daemon程序,而且可以方便的通过命令开启.关闭.重启等操作,而且它管理的进程 ...

  8. Mysql root密码忘记的解决办法

    Windows 版本: 1.打开安装目录下的my.ini 找到 [mysqld] 在下面加入 skip-grant-tables 2. 重启mysql服务 3.打开命令行 依次输入 USE mysql ...

  9. Codeforces839D Winter is here 容斥

    /** 题目:Codeforces839D Winter is here 链接:http://codeforces.com/contest/839/problem/D 题意:给定n个数,求所有的最大公 ...

  10. 关于selenium IDE找不到元素bug

    使用 selenium IDE 录制脚本,经常会发生 这样一种错误. 页面上,明明存在这个元素,就是找不到. 其实原理很简单   , 按钮 点击,没有时间延迟,但是页面加载,需要一段时间. 页面元素还 ...