- 浏览: 344916 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
zy_mensheng:
请问一下 怎么 js没有解析啊 还是钟表图..
调用BIEE提供的web service -
安铁辉:
师兄你很久没更新博客了
Information Dashboard Design读书笔记 -
mojunbin:
很清晰的文章
秒杀相关知识以及技术 -
yanchangjun8102:
楼主你好,我也最近在研究biee的webservice这块,按 ...
调用BIEE提供的web service -
sacredon:
不错,楼主我是看着你的这篇文章写代码调用的BIEE的Web ...
调用BIEE提供的web service
级联和关系维护
Cascade 用来说明当对主对象进行某种操作时,是否对其关联的从对象也作类似的操作,常用的cascade:none,all,save-update,delete,lock,refresh,evict,replicate,persist,merge,delete-orphan(one-to-many).一般对many-to-many,many-to-many不设置级联,在<one-to-one>和<one-to-one>中设置级联。
inverse表示“是否放弃维护关联关系
”(在java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=“true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false
)。
one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。
注:配置成one-to-one的对象不维护关联关系。
接着上面的部门和员工的例子:
department的映射配置文件为:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="hibernate.collections"> <class name="Department"> <id name="id"> <generator class="native" /> </id> <property name="name"/> <map name="emps"> <key column="depart_id" /> <map-key type="string" column="name"/> <one-to-many class="Employee" /> </map> </class> </hibernate-mapping>
程序:
static void add(){ Department depart = new Department(); depart.setName("depart"); Employee e1 = new Employee(); e1.setName("e1"); Employee e2 = new Employee(); e2.setName("e2"); Map<String, Employee> emps = new HashMap<String, Employee>(); emps.put(e1.getName(), e1); emps.put(e2.getName(), e2); depart.setEmps(emps); Session s = HibernateUtil.getSession(); Transaction tx = s.beginTransaction(); //s.save(e1); //s.save(e2); s.save(depart); tx.commit(); }
执行以上代码,程序出现异常:严重: Could not synchronize database state with session
org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: hibernate.collections.Employee
在代码中,department知道了employee.s1和s2未持久化,使得保存department时出现异常。
把配置文件做一下修改,
<map name="emps" cascade="save-update"
>
<key column="depart_id" />
<map-key type="string" column="name"/>
<one-to-many class="Employee" />
</map>
再运行以上代码,就可以正确的保存s1和s2了,因为对他们进行了级联操作,保存department时,也save了employee。
级联操作,可以把上面的选项以逗号分隔开,逐一添加即可。如:
<map name="emps" cascade="save-update,delete,refresh"
></map>
但级联操作也要慎用,要根据自己具体的业务需求来进行相关配置。
还有:
在修改department.hbm.xml配置文件:
<map name="emps"> <key column="depart_id" /> <map-key type="string" column="name"/> <one-to-many class="Employee" /> </map>
执行以下代码:
static void add() { Department depart = new Department(); depart.setName("depart"); Employee e1 = new Employee(); e1.setName("e1"); e1.setDepart(depart); Employee e2 = new Employee(); e2.setName("e2"); e2.setDepart(depart); Map<String, Employee> emps = new HashMap<String, Employee>(); emps.put(e1.getName(), e1); emps.put(e2.getName(), e2); depart.setEmps(emps); Session s = HibernateUtil.getSession(); Transaction tx = s.beginTransaction(); s.save(e1); s.save(e2); s.save(depart); tx.commit(); }
hibernate输出以下sql语句:
Hibernate: insert into Employee (name, depart_id) values (?, ?)
Hibernate: insert into Department (name) values (?)
Hibernate: update Employee set name=?, depart_id=? where id=?
Hibernate: update Employee set name=?, depart_id=? where id=?
Hibernate: update Employee set depart_id=?, name=? where id=?
Hibernate: update Employee set depart_id=?, name=? where id=?
上面的三条插入语句很容易理解。下面的四条更新语句分别对应:
e1.setDepart(depart);
e2.setDepart(depart);
depart.setEmps(emps);
可以验证,如果把 e1.setDepart(depart); e2.setDepart(depart);这两句注释掉,产生的更新语句只有两条:
Hibernate: insert into Employee (name, depart_id) values (?, ?)
Hibernate: insert into Department (name) values (?)
Hibernate: update Employee set depart_id=?, name=? where id=?
Hibernate: update Employee set depart_id=?, name=? where id=?
由此可见,hibernate根据程序代码的执行,采取相应的操作。其实更新语句只需做一次就够了
。对于数据库而言,在程序中,告诉部门有哪些员工,或者告诉员工,你属于那个部门。对于前者,部门需要维护关系。对于后者,员工需要维护关系。他们最终都可以在数据库表中表达出部门和员工的关系。在程序中对两者都手动设定了双方的关系,这样也可以,但显得有些冗余(做了两次更新)。因此,双方都会对关系进行维护,所以,双方都会向数据库提交设定关系的请求,这就带来了数据的重复设置,正如上面的四条更新语句。
解决问题的方案是:我们可以让其中一方放弃对关系的维护。
我们一般让一方放弃对关系的维护,让多方维护。这也比较好理解,正如现实生活中,老师不一定要记住所有学生,但学生记住老师则相对比较容易。
充:inverse不能在有序的集合中使用
。比如一般不这样配置:
<list name="emps" inverse="true"></list> 原因是,list需要维护添加的顺序,如果放弃了关系的维护,那么顺序就也不回得到hibernate的管理。这无疑是矛盾的。
只要在配置文件中做一下修改即可:
<map name="emps" inverse="true">
<key column="depart_id" />
<map-key type="string" column="name"/>
<one-to-many class="Employee" />
</map>
在执行以下代码:
Department depart = new Department(); depart.setName("depart"); Employee e1 = new Employee(); e1.setName("e1"); e1.setDepart(depart); Employee e2 = new Employee(); e2.setName("e2"); e2.setDepart(depart); Map<String, Employee> emps = new HashMap<String, Employee>(); emps.put(e1.getName(), e1); emps.put(e2.getName(), e2); depart.setEmps(emps); Session s = HibernateUtil.getSession(); Transaction tx = s.beginTransaction(); s.save(e1); s.save(e2); s.save(depart); tx.commit();
执行的sql语句为:
Hibernate: insert into Employee (name, depart_id) values (?, ?)
Hibernate: insert into Department (name) values (?)
Hibernate: update Employee set name=?, depart_id=? where id=?
Hibernate: update Employee set name=?, depart_id=? where id=?
分析
:inverse="true"表示放弃对关系的维护。所以上面的两条更新语句是由Employee的setDepart方法产生的。因为关系有Employee来维护。由于department放弃了关系的维护,即使在代码中做了 depart.setEmps(emps)操作,hibernate也会忽略。通过以上方法,可以有效的减少数据库的操作次数,同时不影响关系的建立。
所谓的关系维护,就是更新外键。
改进:
从以上显示的sql语句,可以看出,在插入employee数据是也是插入了depart_id的,只不过是空值,然后插入department,这时就有了depart_id了,这时就去更新employee表,把depart_id更新。其实可以先保存department,这时一开始就有depart_id了,就不会有更新语句了。
代码如下:
static void add() { Department depart = new Department(); depart.setName("depart"); Employee e1 = new Employee(); e1.setName("e1"); e1.setDepart(depart); Employee e2 = new Employee(); e2.setName("e2"); e2.setDepart(depart); Map<String, Employee> emps = new HashMap<String, Employee>(); emps.put(e1.getName(), e1); emps.put(e2.getName(), e2); depart.setEmps(emps); Session s = HibernateUtil.getSession(); Transaction tx = s.beginTransaction(); s.save(depart); s.save(e1); s.save(e2); tx.commit(); }
输出的sql语句为:
Hibernate: insert into Employee (name, depart_id) values (?, ?)
Hibernate: insert into Employee (name, depart_id) values (?, ?)
心得:
根据程序执行过程中,打印输出的sql语句,只需冷静地分析程序的执行过程,不断地改进调优,可以有效的改善程序的性能。
发表评论
-
hibernate学习之十八篇
2009-03-16 17:27 812hibernate不适合的场景: 1,不适合OLAP(on- ... -
hibernate学习之十七篇
2009-03-16 12:31 993零碎知识小结: ◆数据类型: 1,<propert ... -
PO and POJO
2009-03-11 23:49 824原文:http://danni505.blog.51cto.c ... -
hibernate学习之第十六篇
2009-03-11 21:36 1473session context和事务边界 用current_ ... -
hibernate学习之第十五篇
2009-03-11 21:33 1034事务与事务边界 hibernat ... -
Hibernate二级缓存攻略(转)
2009-03-09 22:56 846Hibernate二级缓存攻略(转) 很多人对二级缓存都不太 ... -
hibernate学习之第十四篇
2009-03-09 17:48 1174hibernate的内部缓存 hibernate的缓存分为 ... -
hibernate学习之第十三篇
2009-03-09 17:41 1011load方法的懒加载及原理分析 懒加载的目的,减少不必要的数 ... -
hibernate学习之第十二篇(续)
2009-03-06 19:10 989《四》每个具体类映射 ... -
hibernate学习之第十二篇
2009-03-06 15:57 949《三》混合使用“一个 ... -
hibernate学习之第十一篇(2)
2009-03-05 23:00 897《二》每个子类映射到一张表(joined-subclass) ... -
hibernate学习之第十一篇(1)
2009-03-05 22:55 1479hibernate的继承映射 《一》一张表映射一棵继承树 ... -
hibernate学习之第九篇
2009-03-04 22:52 1344hibernate中的集合类型 引入: Hibernate ... -
hibernate学习之第八篇
2009-03-03 22:11 997组件映射 关联的属性是个复杂类型的持久化类,但不是实体即: ... -
hibernat学习之第七篇
2009-03-03 13:06 959多对多关联关系的映射 在操作和性能方面都不太理想,所以多对 ... -
hibernate 学习之第六篇
2009-03-02 20:31 925基于主键的一对一关联 Person类和IdCard,一对一 ... -
深入浅出hibernate摘录2
2009-03-02 00:38 1513以下内容摘自深入浅出hibernate 在编写代码的时候,尽 ... -
深入浅出hibernate摘录
2009-03-01 19:45 1237以下摘自深入浅出hiberna ... -
hibernate学习之第五篇
2009-03-01 19:43 10771, oracle数据库中,user是关键字,如果用户的表名为 ... -
hibernate学习之第四篇(对象状态)
2009-03-01 19:38 1080session 的几个主要方法 ...
相关推荐
本篇将主要围绕`Hibernate3中文参考手册`展开,深入探讨Hibernate的基础概念、配置、实体映射、查询语言以及其他关键特性。 1. **Hibernate概述** Hibernate是一个开源的ORM框架,它提供了对Java应用程序的数据库...
【hibernate教程-从入门到精通-第4篇(共四篇)共2】这篇教程是关于Java持久层框架Hibernate的学习指南,旨在帮助初学者深入理解并掌握Hibernate的核心概念和技术。Hibernate作为一款强大的对象关系映射(ORM)工具,...
在本篇“Hibernate学习笔记(三)”中,我们将深入探讨Hibernate这一强大的Java持久化框架。Hibernate是一个对象关系映射(ORM)工具,它允许开发者用面向对象的方式处理数据库操作,极大地简化了Java应用程序与...
本教程旨在提供一个全面的Hibernate学习路径,让你能够熟练地运用Hibernate进行数据库操作,提升开发效率。通过深入学习,你将掌握如何利用Hibernate进行对象关系映射(ORM),事务管理,查询优化以及与其他技术如...
【标题】"Hibernate之第1解之-hibernate_demo_1" 涉及的主要内容是对Hibernate框架的基础理解和应用,这是Java开发中一个重要的持久化工具。这篇博客可能详细介绍了如何搭建Hibernate开发环境,以及进行初步的数据...
这篇文档集合了丰富的Hibernate实践知识,对于初学者来说是一份宝贵的资源。 1. **Hibernate核心概念** Hibernate的核心在于持久化对象,它允许我们将Java类映射到数据库表,对象的属性对应于表的列。实体类是Java...
在本篇文章中,我们将深入探讨Hibernate 3.2.5中的核心概念、特性以及它如何简化Java数据库编程。 1. **对象关系映射(ORM)**:Hibernate作为ORM工具,将Java对象与数据库表进行映射,使得开发者可以处理Java对象...
这篇关于“hibernate测试”的文章旨在深入探讨Hibernate的核心概念,以及如何进行有效的测试以确保其在项目中的稳定运行。 1. **Hibernate简介** Hibernate是一个开源的Java库,它为Java应用程序提供了一个框架,...
《Hibernate学习笔记》是一份深度剖析Hibernate框架的教程,旨在为初学者提供全面而深入的指导,帮助他们快速掌握这个强大的Java对象关系映射(ORM)工具。Hibernate作为Java领域中广泛使用的ORM解决方案,它极大地...
【描述】:这篇博客主要涵盖了Hibernate4框架在实际开发中的应用和理解,作者通过个人实践对Hibernate4的核心特性和使用技巧进行了深度解析。 【标签】:“源码”和“工具”这两个标签揭示了本文将涉及到Hibernate4...
这篇文档将对Hibernate的关键概念、配置、实体类、映射文件、会话和事务等方面进行详尽的介绍,以帮助J2EE初学者快速理解和掌握Hibernate。 1. **对象关系映射(ORM)**: ORM是Hibernate的核心,它通过映射文件将...
描述中的"经典heibernate教程,从入门到精通_CSTP-Hibernate02(第二篇,共四篇).ppt"提到了Hibernate教程的第二部分,说明这是一个系列教程,旨在帮助学习者从基础到高级逐步掌握Hibernate。"不错的东西 就是有点看不...
这篇学习笔记将深入探讨Hibernate的基础和关键特性,包括其核心概念、配置、注解使用以及ORM的核心原理。 1. **Hibernate概述** Hibernate是一个开源的ORM框架,由Gavin King创建,它通过提供一个接口,让开发者...
**Hibernate学习资料** Hibernate是一个强大的Java对象关系映射(ORM)框架,它为开发者提供了在Java应用程序中管理和操作数据库的强大工具。这篇文档将深入探讨Hibernate的核心概念、配置、使用方法以及最佳实践,...
在“最经典的hibernate教程_从入门到精通_第四篇”中,我们将会深入探讨以下几个关键知识点: 1. **安装与配置**:学习如何在项目中引入Hibernate库,配置hibernate.cfg.xml文件,设置数据库连接参数,以及如何创建...
10. **性能优化**:探讨缓存策略、批处理更新、预加载等提高Hibernate性能的方法。 这个压缩包中的实例可能会涵盖以上所有或部分知识点,通过运行和分析这些实例,开发者可以深入理解Hibernate的工作原理,并提升在...
【标题】:“Hibernate学习” 【描述】:在深入探讨Hibernate之前,我们首先理解它是一个什么。Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者在Java对象和关系数据库之间建立桥梁,极大地简化了...
本篇文章将深入探讨如何使用Hibernate实现模糊查询和分页功能,这对于任何需要处理大量数据的应用程序来说都是至关重要的技能。 首先,让我们了解Hibernate的核心概念。Hibernate是一个开源的JPA(Java Persistence...
这篇文档旨在提供对Hibernate API的深入理解,帮助开发者更高效地使用Hibernate进行数据库操作。 一、Hibernate概述 Hibernate是Java开发中广泛使用的ORM框架,它提供了一种在Java应用中持久化数据到关系数据库的...
在本篇“我的Hibernate学习笔记(4)完”中,我们将深入探讨Hibernate这一流行的Java对象关系映射(ORM)框架,以及如何通过源码和工具进行高效开发。这篇笔记不仅包含理论知识,还提供了实际操作的指导,以帮助读者更...