inverse属性与双向关联

6 inverse属性与双向关联

使用双向关联执行三句SQL的原因在于:插入room表后,需要插入根据一对多关联的userinfo表,但是插入userinfo表的前提是session.save(room);,也即通过Room实体来维护二者之间的关系。这也就意味着Room实体需要通过自身包含的UserInfo实体一一更新其外键,达到关联的目的。

而inverse属性就提供了另外一个更好的做法,它将关联关系反向交给UserInfo实体来完成,这也就意味着虽然通过session.save(room);来执行插入,但是却是由UserInfo实体来维护二者之间的关系。所做的更改有两个地方,首先是对Room. hbm.xml中一对多部分的修改,见例6.16。

例6.16:增加inverse属性的一对多

<!-- 通过Room实体的users集合属性映射,级联动作为全部 -->

<!-- 将inverse属性设置为true,表示维护动作由UserInfo实体来完成 -->

<set name="users" cascade="all" inverse="true">

<!-- 映射User表的外键roomid -->

<key column="roomid"></key>

<!-- 一对多映射class UserInfo -->

<one-to-many class="UserInfo"></one-to-many>

</set>

其次还需要在实现代码中,将UserInfo与Room实体的关系告诉UserInfo实体,也即让userinfo表的记录得到room表记录的主键。这段实现代码见例6.17。

例6.17:UserInfo实体参考Room实体

public void run() {

//创建Room实体

Room room = new Room();

//设置Room.name

room.setName("rwhome");

//设置Room.roomnumber

room.setRoomnumber("001");

//创建UserInfo实体

UserInfo userInfo = new UserInfo();

//设置UserInfo.name

userInfo.setName("rw");

//设置UserInfo.sex

userInfo.setSex("M");

//保证UserInfo实体得到与Room实体的关系,以帮助由UserInfo来维护外键关联

userInfo.setRoom(room);

//创建UserInfo集合userInfoSet

Set userInfoSet = new HashSet();

//添加UserInfo实体到集合userInfoSet

userInfoSet.add(userInfo);

//设置Room.users(这是一个集合类型)

room.setUsers(userInfoSet);

 

//创建Hibernate Session

Session session = HibernateSessionFactory.currentSession();

//启动事务

Transaction tx = session.beginTransaction();

//持久化Room实体

session.save(room);

//提交事务

tx.commit();

//关闭Hibernate Session

HibernateSessionFactory.closeSession();

}

执行插入表操作,其显示出来的SQL语句如下:

Hibernate:

/* 插入room表 */

insert

into

room

(NAME, roomnumber, id)

values

(?, ?, ?)

Hibernate:

/*插入userinfo表,此时roomid通过UserInfo参考Room实体已经获取并插入了*/

insert

into

userinfo

(NAME, SEX, roomid, id)

values

(?, ?, ?, ?)

这样的SQL语句在批量插入userinfo表时效率高了许多,是双向关联中效率最高的一种插表方式。值得注意的是,执行插表语句中的userInfo.setRoom(room);必须写在代码中,否则SQL语句同样是执行两句插入,但是在userinfo表中将会插入一个为null的roomid。

7 结语

单向关联的功能比双向关联要弱,而且单向关联在操作数据库表时总是会执行三句SQL。因此在一般设计和实现中,通常应该优先选择使用双向关联。而使用双向关联时,inverse属性也是不能忽视的一个重点。通过多端来控制外键值的插入是值得推荐的。

posted @ 2011-11-17 13:23  java学弟  阅读(194)  评论(0编辑  收藏  举报