数据库中表之间的关系:

一对一、一对多、多对多

一对多的建表原则:在多的一方创建外键指向一的一方的主键;

多对多的建表原则:创建一个中间表,中间表中至少有两个字段作为外键分别指向多对多双方的主键;

一对一建表原则:唯一外键对应:假设一对一中的任意一方为多,在多的一方创建外键指向一的一方的主键,将外键设置为唯一

      主键对应:一方的主键作为另一方的主键;

在hibernate中采用java对象关系描述数据表之间的关系:

一对多的映射关系的实现案例:

客户实体类:在hibernate系列一中已经实现点击连接查看:https://www.cnblogs.com/wang-xuan/p/9195795.html

同时在客户实体类中添加属性:

//一个客户对应多个联系人
private Set<LinkMan> linkMans = new HashSet<LinkMan>();
public Set<LinkMan> getLinkMans() {
return linkMans;
}
public void setLinkMans(Set<LinkMan> linkMans) {
this.linkMans = linkMans;
}

实现联系人实体类LinkMan:

package com.itwx.hibernate.pojo;
public class 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;
public Long getLkm_id() {
return lkm_id;
}
public void setLkm_id(Long lkm_id) {
this.lkm_id = lkm_id;
}
public String getLkm_name() {
return lkm_name;
}
public void setLkm_name(String lkm_name) {
this.lkm_name = lkm_name;
}
public String getLkm_gender() {
return lkm_gender;
}
public void setLkm_gender(String lkm_gender) {
this.lkm_gender = lkm_gender;
}
public String getLkm_phone() {
return lkm_phone;
}
public void setLkm_phone(String lkm_phone) {
this.lkm_phone = lkm_phone;
}
public String getLkm_mobile() {
return lkm_mobile;
}
public void setLkm_mobile(String lkm_mobile) {
this.lkm_mobile = lkm_mobile;
}
public String getLkm_email() {
return lkm_email;
}
public void setLkm_email(String lkm_email) {
this.lkm_email = lkm_email;
}
public String getLkm_qq() {
return lkm_qq;
}
public void setLkm_qq(String lkm_qq) {
this.lkm_qq = lkm_qq;
}
public String getLkm_position() {
return lkm_position;
}
public void setLkm_position(String lkm_position) {
this.lkm_position = lkm_position;
}
public String getLkm_memo() {
return lkm_memo;
}
public void setLkm_memo(String lkm_memo) {
this.lkm_memo = lkm_memo;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
}

配置LinkMan.hbm.xml的映射文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.itwx.hibernate.pojo.LinkMan" table="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" />
<property name="lkm_phone" column="lkm_phone" />
<property name="lkm_mobile" column="lkm_mobile" />
<property name="lkm_email" column="lkm_email" />
<property name="lkm_qq" column="lkm_qq" />
<property name="lkm_position" column="lkm_position" />
<!-- 配置关联对象 -->
<!--
many-to-one:代表多对一:
name属性:在实体类中的属性:一的一方的对象的名称;
class属性:一的一方的类的全路径
column:表中的外键,在一的一方中配置的外键;
-->
<many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
column="lkm_cust_id" />
</class>
</hibernate-mapping>

核心配置文件hibernate.cfg.xml

<!-- 配置加载映射文件:全路径-->
<mapping resource="com/itwx/hibernate/pojo/Customer.hbm.xml"/>
<mapping resource="com/itwx/hibernate/pojo/LinkMan.hbm.xml"/>

Customer.hbm.xml配置文件添加一对多的关系映射配置

<!-- 配置多一之间的映射关系 -->
<!--
set标签:name属性:在实体类中的属性,指多的一方的集合的属性名称
key标签:column:多的一方的外键的名称
one-to-many标签:class属性:多的一方的类的全路径
-->
<set name="linkMans">
<key column="lkm_cust_id" />
<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
</set>

测试类中进行测试一对多的关系映射

@Test
public void test4() {
// 获取当前与线程绑定的session
Session session = HibernateUtils.getCurrentSession();
// 开启事务
Transaction transaction = session.beginTransaction();
// 创建关系对象
Customer customer = new Customer();// 此处可以使用带参构造方法
customer.setCust_name("张三");
customer.setCust_source("产品");
LinkMan linkMan1 = new LinkMan();
linkMan1.setLkm_name("周芷若");
linkMan1.setLkm_phone("1223445");
LinkMan linkMan2 = new LinkMan();
linkMan2.setLkm_name("张无忌");
linkMan2.setLkm_gender("男");
// 建立关系
/**
* 首先获取到set集合对象,然后才能进行添加元素; 所以先调用getXXX()方法获取对象,然后add
*/
// 客户关联联系人
customer.getLinkMans().add(linkMan1);
customer.getLinkMans().add(linkMan2);
// 联系人关联客户
linkMan1.setCustomer(customer);
linkMan2.setCustomer(customer);
// 执行操作
session.save(linkMan1);
session.save(linkMan2);
session.save(customer);
// 提交事务
transaction.commit();          //执行结果
/**
* Hibernate: insert into linkman (lkm_name, lkm_gender, lkm_phone,
* lkm_mobile, lkm_email, lkm_qq, lkm_position, lkm_cust_id) values (?,
* ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into linkman (lkm_name,
* lkm_gender, lkm_phone, lkm_mobile, lkm_email, lkm_qq, lkm_position,
* lkm_cust_id) values (?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into
* customer (cust_name, cust_source, cust_industry, cust_level,
* cust_phone, cust_mobile) values (?, ?, ?, ?, ?, ?) Hibernate: update
* linkman set lkm_name=?, lkm_gender=?, lkm_phone=?, lkm_mobile=?,
* lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=? where lkm_id=?
* Hibernate: update linkman set lkm_name=?, lkm_gender=?, lkm_phone=?,
* lkm_mobile=?, lkm_email=?, lkm_qq=?, lkm_position=?, lkm_cust_id=?
* where lkm_id=? Hibernate: update linkman set lkm_cust_id=? where
* lkm_id=? Hibernate: update linkman set lkm_cust_id=? where lkm_id=?
*/
}

级联操作:

指在主控方执行保存、更新和删除操作时,其关联(被控方)也执行相同操作。在映射文件中通过对cascade属性的设置来控制是否对关联对象采用级联操作,级联操作对各种关联关系都是有效的;

级联具有方向性:在保存一的一方级联多的一方和在多的一方可以级联一的一方;

在映射文件中配置cascade=“save-update”;

级联删除和级联保存、更新:谁是主控方,则可以在映射文件中配置cascade=“delete、save-update”,也可以同时配置;

级联删除:在set标签中配置cascade=“delete”或者在mony-to-one中配置cascade属性;

<many-to-one name="customer" class="com.itwx.hibernate.pojo.Customer"
column="lkm_cust_id" cascade="save-update"  />

或者

<set name="linkMans" cascade="delete,save-update" >
<key column="lkm_cust_id" />
<one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>
</set>

防止SQL语句冗余:双向维护关系,持久态对象可以自动更新数据库,更新客户的时候会修改一次外键,更新联系人的时候会修改一次外键,所以会产生SQL语句冗余;

解决方案:一方放弃外键的维护,通常交给多的一方去维护,所以一的一方就需要放弃维护,即需要配置inverse=“true”;

<set name="linkMans" cascade="delete,save-update" inverse="true">            <key column="lkm_cust_id" />            <one-to-many class="com.itwx.hibernate.pojo.LinkMan"/>        </set>

hibernate系列之四相关推荐

  1. 面向对象的程序开发技术C++教学课件系列之四

    面向对象的程序开发技术C++教学课件系列之四 转载于:https://blog.51cto.com/hnxdd/13205

  2. [转]DPM2012系列之四:配置邮件报警功能

    DPM2012系列之四:配置邮件报警功能 源地址:http://543925535.blog.51cto.com/639838/1049285 ============================ ...

  3. [Hibernate系列—] 2. 创建SessionFactory 与 Session

    Configuration 对象创建 要创建SessionFactory , 首先要创建Configuration 对象. 这个对象就是去读取hibernate 的一些配置信息. 默认状况下, hib ...

  4. 【SSH框架】之Hibernate系列一

    微信公众号:compassblog 欢迎关注.转发,互相学习,共同进步! 有任何问题,请后台留言联系! 1.Hibernate框架概述 (1).什么是Hibernate Hibernate是一个开放源 ...

  5. 进程——Windows核心编程学习手札系列之四

    进程 --Windows核心编程学习手札系列之四 进程是一个正在运行的程序的实例,有两个部分组成:一个是操作系统用来管理进程的内核对象,内核对象是系统用来存放关于进程的统计信息的地方:另一个是地址空间 ...

  6. (Hibernate进阶)Hibernate系列——总结篇(九)

    这篇博文是hibernate系列的最后一篇,既然是最后一篇,我们就应该进行一下从头到尾,整体上的总结,将这个系列的内容融会贯通. 概念 Hibernate是一个对象关系映射框架,当然从分层的角度看,我 ...

  7. mongodb与java结合_MongoDB初探系列之四:MongoDB与Java共舞

    MongoDB初探系列之四:MongoDB与Java共舞 来源:互联网 作者:佚名 时间:2015-08-05 08:20 对各位注意到这个帖子的朋友说一声对不起,我不是故意的测试服务器一直没关,一忙 ...

  8. nginx系列之四:web服务器

    ** 前言 ** nginx系列之一:nginx入门 nginx系列之二:配置文件解读 nginx系列之三:日志配置 nginx系列之四:web服务器 nginx系列之五: 负载均衡 nginx系列之 ...

  9. ASP.NET企业开发框架IsLine FrameWork系列之四--DataProvider 数据访问(上)

    ASP.NET企业开发框架IsLine FrameWork系列之四--DataProvider 数据访问(上) 接上文 DataProvider是日常编程中最常用的Provider,它为项目提供了与数 ...

最新文章

  1. java HashMap的使用
  2. 关于表达式i+++i+++i++有感
  3. Mockito框架学习 - how does expected annotation work
  4. 用SQL Server 2017图形数据库替换数据仓库中的桥表
  5. Android中service的生命周期
  6. DotNet中的集合对象(2): Hashtable
  7. 安卓饼状图设置软件_Android自定义控件实现饼状图
  8. windows服务器连接教程-手机连接电脑连接
  9. python写txt怎么首行缩进_text-indent首行缩进两个字符和图片缩进的问题
  10. CMD如何直接运行文件
  11. 竹子的精神高山流水,赞美竹子的句子,竹子散文
  12. android音频编辑之音频裁剪
  13. iOS app已经上架可供销售,但是在AppStore上搜不到的解决办法
  14. 求生之路服务器参数配置
  15. python数据分析师 前景_数据分析师是否有前途
  16. 消防工程师 2.1 自动喷水灭火系统-湿式
  17. java毕业设计热门股票推荐系统源码+lw文档+mybatis+系统+mysql数据库+调试
  18. 国嵌C语言总结(1-5)
  19. PaddleSeg快速标注图像
  20. 未来科技的发展趋势,对人类生活有哪些影响?

热门文章

  1. Exchange Server 2013多域名证书申请
  2. 【IOS下载】Cisco IOS下载
  3. fail-fast与fail-safe工作机制
  4. pika集群水平扩展——让性能容量不再受限
  5. Dubbo消费者服务的订阅
  6. 服务器c盘windows文件夹太大,Win10C盘windows文件夹过大怎么办?Win10C盘windows文件夹过大的解决方法...
  7. c语言中错误为ffblk未定义,C语言中头文件及函数的含意的总分类
  8. mysql修改字段null为空字符串
  9. laravel引入自定义全局函数
  10. Mybatis面试题-日更