hibernate多表操作详解
来源:互联网 发布:base64.js下载 编辑:程序博客网 时间:2024/06/06 17:17
一.简介
在进行关系型数据库设计时,表与表之间的关系往往不是独立的,而是相互关联的,这就是所谓的多表设计。一般来说,数据库表与表包含以下几种关系。
建表原则
一对一:主键对应,一方的主键作为另一方的主键。
一对多:在多的一方创建外键指向一的一方的主键
多对多:创建一个中间表,中间表的最少两个字段作为外键分别指向多对多双方的主键。
此种关系在hibernate中用Java对象表示如下:
class Aclass Aclass A
{{{
B b;Set<B> bs;Set<B> bs}}}class Bclass Bclass B
{{{
A a;Set<A> asA a;}}}
一对一的关系一对多的关系多对多的关系
在一般情况下,一对多的情况是比较常见的,比如学生与老师的关系,部门与员工的关系,客户与联系人的关系,所以,下面将以一对多关系为例说明hibernate是怎么建立多表之间的关系的。
二.hibernate的一对多关系映射操作实例
1.例子说明:
本实例建立两个表,分别是联系人表和客户表(典型的客户管理系统中经常遇到的),其中一个客户拥有多个联系人,即客户与联系人的关系为一对多。所以,联系人中存在外键,该外键指向客户。具体描述如下。
2.创建hibernate实体
联系人实体
public class LinkMan {
private Long lkm_id;private Character lkm_gender;private String lkm_name;private String lkm_phone;private String lkm_email;private String lkm_qq;private String lkm_mobile;private String lkm_memo;private String lkm_position;//注意这里是关键写法,在多的一方的实体中创建一个类型为一的一方的属性private Customer customer ;get方法....set方法....}
客户实体public class Customer {private Long cust_id;private String cust_name;private String cust_source;private String cust_industry;private String cust_level;private String cust_linkman;private String cust_phone;private String cust_mobile;//注意这里是关键,在一的一方的实体中创建一个泛型类型为多的一方的set集合。private Set<LinkMan> linkMens = new HashSet<LinkMan>();}
2.创建映射关系联系人映射关系的写法(多的一方)
前面普通字段不再累述,可参见笔者前一篇博客。重点讲述关联对象的配置。一的一方使用many-to-one元素。
<many-to-one name="customer" column="lkm_cust_id" class="Customer的完整类名" ></many-to-one>name属性:引用属性名
column属性: 外键列名
class属性: 与我关联的对象完整类名
客户映射关系的写法(一的一方)
多的一方使用set元素来描述被映射类的set集合,
<set name="linkMens" ><key column="lkm_cust_id" ></key><one-to-many class="LinkMan的完整类名" /></set>key标签的column属性:用来描述对应文件多的一方的主键名称。
one-to-many元素 的class属性:用来描述映射关联类
3.将映射添加到hibernate主配置文件中
<mapping resource="Customer.hbm.xml文件的包路径" /><mapping resource="LinkMan.hbm.xml的包路径" />4.编写测试函数
public void text(){//1 获得sessionSession session = HibernateUtils.openSession();//2 开启事务Transaction tx = session.beginTransaction();//-------------------------------------------------//创建一个客户Customer c = new Customer();c.setCust_name("谷歌");//创建多个联系人LinkMan lm1 = new LinkMan();lm1.setLkm_name("crc");LinkMan lm2 = new LinkMan();lm2.setLkm_name("psl");//表达一对多,客户下有多个联系人c.getLinkMens().add(lm1);c.getLinkMens().add(lm2);//表达对对对,联系人属于哪个客户lm1.setCustomer(c);lm2.setCustomer(c);//若无设置级联操作,则所有对象均要保存,否则出现瞬时对象异常。session.save(c);
session.save(lm1);session.save(lm2);//4提交事务tx.commit();//5关闭资源session.close();}
若制定Junit测试后为绿条,且数据库新创建两个表,说明hibernate执行多表关联操作成功。三.hibernate多表关系映射的级联操作
所谓级联操作是指当主控方执行保存,更新,删除操作时,其关联的对象也会执行相同的操作。在映射文件中通过set元素的
属性cascade来配置。主控方的选择是任意的,但一般习惯主控方选择为一的一方。
1.级联保存,关键词为save-update
配置如下代码:
<set name="linkMens" cascade="save-update" ><key column="lkm_cust_id" ></key><one-to-many class="LinkMan" /></set>
此时,只要执行保存客户,联系人会跟着保存下来。2.级联删除,关键词为delete
配置代码如下
<set name="linkMens" cascade="delete" ><key column="lkm_cust_id" ></key><one-to-many class="LinkMan" /></set>
这时,在代码中删除了客户,与其关联的联系人也会跟着删除,但是,要注意,这种操作比较危险,一般不用。
要注意,级联保存和级联删除是可以同时配置 的。
四.双向关联产生多余的SQL语句 的问题
在实行表对象关联时操作时,SQL语句有可能会重复执行,出现这种问题的原因是,两个表对象都维护了关系,持久化对象可以自动更新数据库,更新客户时会修改一次外键,更新联系人时也会修改一次外键,因此产生多余的SQL语句。解决方法是使其中一方放弃维护关系即可。一般情况下,一的一方放弃维护关系。执行如下配置即可。
<set name="linkMens" inverse="true" cascade="delete,save-update" ><key column="lkm_cust_id" ></key><one-to-many class="LinkMan" /></set>
inverse的默认值为false,代表不放弃外键维护权,修改为true,即放弃维护。(注意,这一点与我们的正常思维相反)五.总结
数据库的多表设计问题是一个重要的知识点,本博客以一对多关系为例,介绍了hibernate中的多表操作。感兴趣的朋友可以
深入研究多对多的表关系,或者三表以及更多表的hibernate操作。
- hibernate多表操作详解
- hibernate级联操作详解
- hibernate级联操作详解
- Hibernate + Spring 操作 Lob 详解
- Hibernate-day04 Hibernate 多表操作 Hibernate优化 检索策略
- Hibernate多表关联操作
- Hibernate中的多表操作
- Hibernate对BLOB CLOB操作详解
- Hibernate的级联操作详解(转)
- Hibernate Session 操作数据库的方法详解
- Hibernate详解(一)--session操作对象
- Hibernate Session 操作数据库的方法详解
- 整合Struts+Hibernate+Spring应用开发 Hibernate hql操作详解
- hibernate多表操作之多对多
- Hibernate超简单多表操作
- Hibernate之多对多表,操作实例
- Hibernate 查询与多表操作
- hibernate 一对多表配置及操作
- JS的的作用域和闭包
- 第四十六篇:MAC下使用 Node.js 实现一个 WebServer 服务器
- SSL P1520 牛的rp
- MATLAB实现PLA算法
- jQuery选择器(:nth-child(n))详解
- hibernate多表操作详解
- xlistview加载网页内容上拉刷新下拉加载
- Hilditch 细化(实现二)
- 【NYOJ
- 设计模式之---适配器模式
- Django REST framework-Quickstart
- python线程的使用方法以及全局变量的应用
- 稳定排序和不稳定排序之分!
- [Azure]使用Powershell克隆ARM虚拟机(非托管磁盘)