一、一对多|多对一

1、关系表达

 表中的表达

  

  实体中的表达

  

  orm元数据中表达

    一对多

        <!-- 集合,一对多关系,在配置文件中配置 -->
<!--
name属性:集合属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<set name="linkMens" inverse="true" cascade="delete" >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>

    多对一

        <!-- 多对一 -->
<!--
name属性:引用属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
-->
<many-to-one name="customer" column="lkm_cust_id" class="Customer" >
</many-to-one>

2、操作

  操作关联属性

        //3操作
Customer c = new Customer();
c.setCust_name("传智播客"); LinkMan lm1 = new LinkMan();
lm1.setLkm_name("黎活明"); LinkMan lm2 = new LinkMan();
lm2.setLkm_name("刘悦东"); //表达一对多,客户下有多个联系人
c.getLinkMens().add(lm1);
c.getLinkMens().add(lm2); //表达对对对,联系人属于哪个客户
lm1.setCustomer(c);
lm2.setCustomer(c); session.save(c);
session.save(lm1);
session.save(lm2);

3、进阶操作

  级联操作

         <!--
级联操作: cascade
save-update: 级联保存更新
delete:级联删除
all:save-update+delete
级联操作: 简化操作.目的就是为了少些两行代码.
-->
        <set name="linkMens" inverse="true" cascade="delete"  >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>

  结论: 简化操作.一定要用,save-update,不建议使用delete.

  关系维护

  

  在保存时.两方都会维护外键关系.关系维护两次,冗余了. 多余的维护关系语句,显然是客户这一端在维护关系

          <!-- inverse属性: 配置关系是否维护.
true: customer不维护关系
false(默认值): customer维护关系 inverse属性: 性能优化.提高关系维护的性能.
原则: 无论怎么放弃,总有一方必须要维护关系.
一对多关系中: 一的一方放弃.也只能一的一方放弃.多的一方不能放弃.
-->
<set name="linkMens" inverse="true" cascade="delete" >
<key column="lkm_cust_id" ></key>
<one-to-many class="LinkMan" />
</set>

二、多对多

1、关系表达

 表中的表达

  

  对象中

  

  orm元数据

        <!-- 多对多关系表达 -->
<!--
name: 集合属性名
table: 配置中间表名
key
|-column:外键,别人引用"我"的外键列名
class: 我与哪个类是多对多关系
column:外键.我引用比人的外键列名
-->
<!-- cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除
结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.
-->
<set name="roles" table="sys_user_role" cascade="save-update" >
<key column="user_id" ></key>
<many-to-many class="Role" column="role_id" ></many-to-many>
</set>

2、操作

  操作关联属性

        //3> 用户表达关系
u1.getRoles().add(r1);
u1.getRoles().add(r2); u2.getRoles().add(r1);
u2.getRoles().add(r2); //4> 角色表达关系
r1.getUsers().add(u1);
r1.getUsers().add(u2); r2.getUsers().add(u1);
r2.getUsers().add(u2); //5> 调用Save方法一次保存
session.save(u1);
session.save(u2);
session.save(r1);
session.save(r2);

3、操作进阶

  inverse属性

    <!-- 使用inverse属性
true: 放弃维护外键关系
false(默认值):维护关系 结论: 将来在开发中,如果遇到多对多关系.一定要选择一方放弃维护关系.
一般谁来放弃要看业务方向. 例如录入员工时,需要为员工指定所属角色.
那么业务方向就是由员工维护角色. 角色不需要维护与员工关系.角色放弃维护
-->
<set name="users" table="sys_user_role" inverse="true" >
<key column="role_id" ></key>
<many-to-many class="User" column="user_id" ></many-to-many>
</set>

  级联属性

  

         <!-- cascade级联操作:
save-update: 级联保存更新
delete:级联删除
all:级联保存更新+级联删除
结论: cascade简化代码书写.该属性使不使用无所谓. 建议要用只用save-update.
如果使用delete操作太过危险.尤其在多对多中.不建议使用.
-->
<set name="roles" table="sys_user_role" cascade="save-update" >
<key column="user_id" ></key>
<many-to-many class="Role" column="role_id" ></many-to-many>
</set>

三、练习:添加联系人

  servlet:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1> 获得参数并封装LinkMan对象中
LinkMan lm = new LinkMan();
try {
BeanUtils.populate(lm, request.getParameterMap());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//2> 调用Service保存LinkMan对象
lms .save(lm);
//3> 重定向到LinkMan的列表(404)
response.sendRedirect(request.getContextPath()+"/ListLinkManServlet");
}

  service:

    private CustomerDao cd =new CustomerDaoImpl();
private LinkManDao lmd = new LinkManDaoImpl();
public void save(LinkMan lm) {
//打开事务
HibernateUtils.getCurrentSession().beginTransaction(); try {
//1 根据客户id获得客户对象
Long cust_id = lm.getCust_id();
Customer c = cd.getById(cust_id);
//2 将客户放入LinkMan中表达关系
lm.setCustomer(c);
//3 保存LinkMan
lmd.save(lm);
} catch (Exception e) {
e.printStackTrace();
//回滚事务
HibernateUtils.getCurrentSession().getTransaction().rollback();
}
//提交事务
HibernateUtils.getCurrentSession().getTransaction().commit(); }

  dao:

    public void save(LinkMan lm) {
//1 获得session
Session session = HibernateUtils.getCurrentSession();
session.save(lm);
}

JAVAEE学习——hibernate03:多表操作详解、级联、关系维护和练习:添加联系人的更多相关文章

  1. 【JAVAEE学习笔记】hibernate03:多表操作详解、级联、关系维护和练习:添加联系人

    一.一对多|多对一 1.关系表达 表中的表达 实体中的表达 orm元数据中表达 一对多 <!-- 集合,一对多关系,在配置文件中配置 --> <!-- name属性:集合属性名 co ...

  2. [转载]JavaEE学习篇之——JQuery技术详解

    原文链接:http://blog.csdn.net/jiangwei0910410003/article/details/32102187 1.简介2.工具3.jQuery对象 1.DOM对象转化成j ...

  3. MySQL 操作详解

    MySQL 操作详解 一.实验简介 本节实验中学习并实践 MySQL 上创建数据库.创建表.查找信息等详细的语法及参数使用方法. 二.创建并使用数据库 1. 创建并选择数据库 使用SHOW语句找出服务 ...

  4. [转帖]Windows注册表内容详解

    Windows注册表内容详解 来源:http://blog.sina.com.cn/s/blog_4d41e2690100q33v.html 对 windows注册表一知半解 不是很清晰 这里学习一下 ...

  5. 重新学习MySQL数据库7:详解MyIsam与InnoDB引擎的锁实现

    重新学习Mysql数据库7:详解MyIsam与InnoDB引擎的锁实现 说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同. 三类常见引擎: MyIsam :不支持事务,不 ...

  6. Python对Excel操作详解

      Python对Excel操作详解 文档摘要: 本文档主要介绍如何通过python对office excel进行读写操作,使用了xlrd.xlwt和xlutils模块.另外还演示了如何通过Tcl   ...

  7. oracle表分区详解

    原文来自:http://www.cnblogs.com/leiOOlei/archive/2012/06/08/2541306.html oracle表分区详解 从以下几个方面来整理关于分区表的概念及 ...

  8. [Android新手区] SQLite 操作详解--SQL语法

    该文章完全摘自转自:北大青鸟[Android新手区] SQLite 操作详解--SQL语法  :http://home.bdqn.cn/thread-49363-1-1.html SQLite库可以解 ...

  9. Oracle表空间详解

    Oracle表空间详解 1.表空间的分类 Oracle数据库把表空间分为两类:系统表空间和非系统表空间. 1.1系统表空间指的是数据库系统创建时需要的表空间,这些表空间在数据库创建时自动创建,是每个数 ...

随机推荐

  1. HDU 2685 GCD推导

    求$(a^n-1,a^m-1) \mod k$,自己手推,或者直接引用结论$(a^n-1,a^m-1) \equiv a^{(n,m)}-1 \mod k$ /** @Date : 2017-09-2 ...

  2. JAVA多线程提高五:原子性操作类的应用

    当程序更新一个变量时,如果多线程同时更新这个变量,可能得到期望之外的值,比如变量i=1,A线程更新i+1,B线程也更新i+1,经过两个线程操作之后可能i不等于3,而是等于2.因为A和B线程在更新变量i ...

  3. PHP与数据库

    连接数据库 Connect 访问数据库的数据之前,先要与数据库建立连接,使用mysql_connect()方法与数据库建立连接. mysql_connect()参数 <?php //server ...

  4. 赶快收藏!16款最流行的 JavaScript 框架

    下面为大家介绍 16款最流行的 JavaScript 框架,赶快收藏! 1. jQuery – Javascript框架 jQuery 是最流行的 JavaScript 框架,它简化了HTML 文档遍 ...

  5. 用Vue来实现图片上传多种方式

    没有业务场景的功能都是耍流氓,那么我们先来模拟一个需要实现的业务场景.假设我们要做一个后台系统添加商品的页面,有一些商品名称.信息等字段,还有需要上传商品轮播图的需求. 我们就以Vue.Element ...

  6. 【洛谷 P2764】 最小路径覆盖问题(最大流)

    题目链接 首先有\(n\)条路径,每条路径就是一个点,然后尽量合并,答案就是点数-合并数. 套路拆点,源连入,出连汇,原有的边入出连. 最大流就是最大合并数,第一问解决. 然后怎么输出方案? 我是找到 ...

  7. CSS 中 nth-child 和 nth-of-type 的区别

    假设有如下代码结构,想要查找 Piggy 那个 p <section> <h1>Words</h1> <p>Little</p> <p ...

  8. 巅峰极客CTF writeup[上]

    经验教训 1.CTF不比实战,最好不要死磕.死磕就输了.我就是死磕在缓存文件死的.真的惭愧: 2.对于flag的位置不要太局限于web目录下,如果是命令执行直接上find / -name flag*: ...

  9. flask插件系列之flask_celery异步任务神器

    现在继续学习在集成的框架中如何使用celery. 在Flask中使用celery 在Flask中集成celery需要做到两点: 创建celery的实例对象的名字必须是flask应用程序app的名字,否 ...

  10. linux内核sysfs详解【转】

    转自:http://blog.csdn.net/skyflying2012/article/details/11783847 "sysfs is a ram-based filesystem ...