- 浏览: 279430 次
最新评论
-
liupengjun1:
学习看看!!!
Dom4j的使用(全而好的文章) -
李君寻:
条理清晰,有示例有分析,好文档,谢谢分享
Dom4j的使用(全而好的文章) -
TaoistWar:
nintenyun 写道TaoistWar 写道垃圾,不如看D ...
Dom4j的使用(全而好的文章) -
shangs2010:
写的真仔细,多谢!真好!
Dom4j的使用(全而好的文章) -
a346063587:
顶。。真的很好哈。。。。
Dom4j的使用(全而好的文章)
java 代码
- 双向关联与inverse设定
- 之前我们对User与Room作了单向的多对一以及反过来的一对多关联,我们也可以让User与Room彼此参考,形成双向关联,就User与Room对象,具体来说,就是将程序如下设计:
- User.java
- package onlyfun.caterpillar;
- public class User {
- private long id;
- private String name;
- private Room room;
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Room getRoom() {
- return room;
- }
- public void setRoom(Room room) {
- this.room = room;
- }
- }
- Room.java
- package onlyfun.caterpillar;
- import java.util.*;
- public class Room {
- private long id;
- private String address;
- private Set users = new HashSet();
- public long getId() {
- return id;
- }
- public void setId(long id) {
- this.id = id;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public Set getUsers() {
- return users;
- }
- public void setUsers(Set users) {
- this.users = users;
- }
- }
- 而其对应的映射文件如下,首先是User.hbm.xml:
- User.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping
- PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
- <hibernate-mapping>
- <class name="onlyfun.caterpillar.User" table="USER">
- <id name="id" column="USER_ID" unsaved-value="0">
- <generator class="increment"/>
- </id>
- <property name="name">
- <column name="NAME" length="16" not-null="true"/>
- </property>
- <many-to-one name="room"
- column="ROOM_ID"
- class="onlyfun.caterpillar.Room"/>
- </class>
- </hibernate-mapping>
- 再来是Room.hbm.xml:
- Room.hbm.xml
- <?xml version="1.0"?>
- <!DOCTYPE hibernate-mapping
- PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
- "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
- <hibernate-mapping>
- <class name="onlyfun.caterpillar.Room" table="ROOM">
- <id name="id" column="ROOM_ID" unsaved-value="0">
- <generator class="increment"/>
- </id>
- <property name="address" type="string"/>
- <set name="users" table="USER" cascade="all">
- <key column="ROOM_ID"/>
- <one-to-many class="onlyfun.caterpillar.User"/>
- </set>
- </class>
- </hibernate-mapping>
- 这就形成了User与Room之间的双向关联映射,我们可以使用以下的程序进行测试:
- HibernateTest.java
- import onlyfun.caterpillar.*;
- import net.sf.hibernate.*;
- import net.sf.hibernate.cfg.*;
- public class HibernateTest {
- public static void main(String[] args) throws HibernateException {
- SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
- Room room = new Room();
- room.setAddress("NTU-M8-419");
- User user1 = new User();
- user1.setName("bush");
- User user2 = new User();
- user2.setName("bush");
- /*
- * 因为没有设定inverser,所以只须从parent维护即可
- */
- //user1.setRoom(room);
- //user2.setRoom(room);
- room.getUsers().add(user1);
- room.getUsers().add(user2);
- Session session = sessionFactory.openSession();
- Transaction tx= session.beginTransaction();
- session.save(room);
- tx.commit();
- session.close();
- sessionFactory.close();
- }
- }
- 基本上就数据的储存来说,这样就已经足够,但这样的设计会有效能问题,显然的,这个程序将Room与User之间的关联交由Room来维持,就Room而言,它要先储存自已,然后储存其所包括的多个User,之后再对每一个User更新(update)对自己(Room)的关联,具体而言,这个程序必须实行以下的SQL:
- Hibernate: insert into ROOM (address, ROOM_ID) values (?, ?)
- Hibernate: insert into USER (NAME, ROOM_ID, USER_ID) values (?, ?, ?)
- Hibernate: insert into USER (NAME, ROOM_ID, USER_ID) values (?, ?, ?)
- Hibernate: update USER set ROOM_ID=? where USER_ID=?
- Hibernate: update USER set ROOM_ID=? where USER_ID=?
- 就Room而言,它并不知道其所包括的User是不是一个已储存的对象,或者即使为已储存对象,也不知道USER表格上的ROOM_ID是不是参考至ROOM表格的ROOM_ID上,所以它必须针对自己所包括的User对象一个个进行更新,以确保USER表格上的ROOM_ID是指向自己。
- 如果将关联的维护交给User的话会比较容易,因为每个User都对应至一个Room,在储存时并用像Room一样必须对Set中的每个对象作检查,为了将关联的维护交给User,我们可以在Room.hbm.xml中的<set>修改,加上inverse="true",表示将关联的维护「反过来」交给User作:
- Room.java
- <set name="users" table="USER" inverse="true" cascade="all">
- <key column="ROOM_ID"/>
- <one-to-many class="onlyfun.caterpillar.User"/>
- </set>
- 由于将关联的维护交给User来作了,所以我们必须在储存时,明确的将Room设定给User,也就是说,必须这样作:
- /*
- * 因为有user维护关联,所以必须呼叫setRoom
- */
- user1.setRoom(room);
- user2.setRoom(room);
- room.getUsers().add(user1);
- room.getUsers().add(user2);
- 这比不加上inverse="true"设定时多了个指定的动作,您必须多键几个字,所带来的是效率上的增加,Hibernate的持久层管理员会先储存Room,然后储存User,如此就可以省去之前再进行更新的动作,具体来说,就是会执行以下的SQL:
- Hibernate: insert into ROOM (address, ROOM_ID) values (?, ?)
- Hibernate: insert into USER (NAME, ROOM_ID, USER_ID) values (?, ?, ?)
- Hibernate: insert into USER (NAME, ROOM_ID, USER_ID) values (?, ?, ?)
- 与先前不同的是,由于关联交给了User维护,所以这次Room不用一一更新USER以确定每个ROOM_ID都指向自已。
- 如果指定了inverse="true",而不确实的将Room指定给User会如何?那么User与Room会各自储存,但彼此没有关联,也就是User将不会参考至Room,USER表格的ROOM_ID将为null,例如:
- mysql> select * from USER;
- +---------+------+---------+
- | USER_ID | NAME | ROOM_ID |
- +---------+------+---------+
- | 1 | bush | NULL |
- +---------+------+---------+
- mysql> select * from ROOM;
- +---------+------------+
- | ROOM_ID | address |
- +---------+------------+
- | 1 | NTU-M8-419 |
- +---------+------------+
- 作个总结,在设立双向关联时,关联由多对一中「多」的哪一方维护,会比由「一」的哪一方维护来的方便,在Hibernate可以藉由inverse来设定,不设定inverse基本上也可以运行,但是效能会较差。
- 设定了inverse,必须要明确的设定双方的参考,以这个主题的例子,Room要设定给User,而User也要知道Room的存在,这比不设定inverse需要键入较多的字,但从另一方面,比较符 合程序设计的直觉(单看User与Room类别,两者要互相参考时,本来就要明确设定)。
评论
4 楼
franciswang
2009-02-19
我的配置文件和你的一样,但是为什么还是先存ROOM再存USER然后UPDATE USER的外键。
3 楼
heitianba
2009-02-10
2 楼
tianlwww
2008-12-24
700多人看,没一个回复的,太让人心寒.............
1 楼
tianlwww
2008-12-24
发表评论
-
java mysql 备份
2007-08-08 11:37 4939首先,设置mysql的环境变量(在path中添加%MYSQL_ ... -
用ajax实现级联菜单
2007-08-08 11:35 3046张盈盈 11:15:18 <script> ... -
网页定位问题
2007-06-09 17:08 2082问题:一个网页显示了10道题,我看到第8道,发现它有错误,通过 ... -
Hibernate提供了以下几种内置标识符生成器
2007-04-24 11:25 2100Generator元素用来设定标识符生成器.Hibernate ... -
hibernate的父子关系及inverse
2007-04-24 10:25 1892inverse="true"的问题 inv ... -
Hibernate中outer-join、lazy 、fetch join关键字的使用
2007-04-24 09:48 132681、outer-join关键字(many-to ... -
关于Hibernate的unsaved-value
2007-04-24 09:26 1610关于Hibernate的unsaved-value unsa ... -
sun.net.ftp.FtpClient的函数说明
2007-03-20 16:23 11687sun.net.ftp.FtpClient.,该类库主要提供了 ... -
JAVA操作Excel的方法
2007-03-17 11:11 1889此操作使用POI类库,请到以下URL下载: http ... -
小知识点
2007-03-11 14:14 14101从C盘的目录切换到D盘,不用cd命令,直接输入 C:\Doc ... -
Linux Squid 代理修改配置
2007-03-09 13:59 1607附件中 -
jstl(jsp标准标签)
2007-02-02 17:00 1416附件中 -
spring mvc 中文乱码问题解决
2007-01-29 16:35 11344在eclipse环境里,页面传输数据的时候通常用ISO-885 ... -
Dom4j的使用(全而好的文章)
2007-01-24 17:43 136822Dom4j 使用简介 作者: ... -
dom4jAPI[1]--用dom4j建立,修改XML文档,并解决格式化输出和中文问题
2007-01-24 16:41 4692import java.io.File;<o:p> ... -
MD5加密的Java Bean
2007-01-22 09:20 1914MD5 算法的Java Bean- - ... -
spring配置中<context-param> 和<init-param>的 区别
2007-01-11 13:48 4448如果我们直接作为tomcat中的一部分.那么我们一定要用con ... -
log4j详解
2007-01-07 15:08 2532...
相关推荐
彻底明白Hibernate中的Inverse
Hibernate中Inverse和Cascade的区别.html
Hibernate中Cascade和inverse的区别,讲解的很详细
JavaEE学习笔记之Hibernate表关系之一对多(inverse详解)
Hibernate中cascade与inverse属性详解
Hibernate中cascade和inverse应用
hibernate inverse和cascade的详细讲解,相当详细全面的对inverse和cascade区别和用法的讲解
hibernate inverse 个人总结
hibernate 级联(cascade和inverse)一对多,Jar包,数据库建表语句都好了,只要修改一下,数据库配置文件,就可以使用了,使用junit进行测试。
于Hibernate中 cascade 与 inverse 的理解。 您买的Hibernate书是哪一本呢? 孙卫琴的精通Hibernate,还是 深入浅出Hibernate还是那本。。。 我是两本都买了,总体来说还可以,但是,有的地方讲的比较书面化,比如...
hibernate集合映射inverse和cascade详解.txt
hibernate中一对一,一对多,多对多关系的配置,延迟加载,cascade,inverse hibernate查询方式概述,HQL查询,QBC查询,分页,结果集封装方式 ,高级查询 查询的优化,一级缓存,二级缓存,批量查询,注解方式
inverse Hibernate_级联关系说明_-_关于cascade和inverse的用法
hibernate中inverse作用。我是一个Hibernate的初学者,前两天刚刚研究了一下inverse属性,有所心得。故把自己的小例子贴出来,与大家共享。
多对多双向关联 <br>注意映射规则: <set name="roles" table="t_user_role"><br> <key column="userid"/><br> <many-to-many class="com.bjsxt.hibernate.Role" column="roleid"/> </set><br> table...
Hibernate fetch lazy cascade inverse 关键字
Hibernate中cascade和inverse的相关
hibernate注解的方法的详解
hibernate 3中的缓存小结 2.2. 一级缓存的管理: 当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load(),以及调用查询接口的list()、iterate()或filter()方法时,如果在Session缓存中还不存在...