随笔 - 6  文章 - 129  trackbacks - 0
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

常用链接

留言簿(14)

随笔档案(6)

文章分类(467)

文章档案(423)

相册

收藏夹(18)

JAVA

搜索

  •  

积分与排名

  • 积分 - 821535
  • 排名 - 49

最新评论

阅读排行榜

评论排行榜

映射中的inverse

  首先要明确一点,inverse只存在于集合标记的元素中,Hibernate所提供的集合元素包括<set/>,
<map/>,<list/>,和<bag/>.
  inverse属性的作用是是否将对集合的修改反应到数据库中.也就是说当inverse="false"时,对
集合对象的修改会被反映到数据库中,而inverse="true"时,则不会对数据库进行相应的处理.
  inverse的默认值是等于false.
  inverse所描述的是对象之间关联关系的维护方式.
  换个角度来理解,inverse属性的作用也可以理解为设置对象之间关联关系的维护方在哪一端.当
inverse="false"时,表明对象之间的关联关系由本方来进行维护.而当其inverse="true"时则表明对象
之间的关联关系由关联的另一方进行维护.

下面以一个例子说明
一对多关联关系

用户实体(User)和留言实体(Message)之间的一对多关联关系.
在User.hbm.xml配置文件中
...
  <set name="messages" inverse="false" cascade="all" >
         <key>
            <column name="user_id" length="32" />
         </key>
         <one-to-many class="dgut.ke.blog.model.Message" />
    </set>
...
保存实体的情况:
将inverse的值设为false,控制台输出的语句如下
(Message对象自己需要发出update语句来维护两者的关联关系)
Hibernate: insert into user (name, password, id) values (?, ?, ?)
Hibernate: insert into message (title, content, pubdate, user_id, id) values (?, ?, ?, ?, ?)
Hibernate: update message set user_id=? where id=?
当把inverse的值设置为true时,则上面的第三条SQL语句则不会发出.关联关系由User进行维护.
删除子对象的情况:
将inverse的值设为false,控制台输出的语句如下
Hibernate: update message set user_id=null where user_id=?
Hibernate: delete from message where id=?
同样将inverse的值设为true,则update语句不会发出.

多对多的关联关系

  注:在设置多对多关系的inverse属性的时候,不能两个对象都将其设置为true,否则这两个对象就不能维护
两者之间的关系了.
用户实体(User)和角色(Role)之间的多对多关联关系
相关配置文件
User.hbm.xml
...
    <set name="roles" table="user_role" cascade="save-update">
       <key column="user_id" />
       <many-to-many class="dgut.ke.blog.model.Role" column="role_id" />
    </set>
...
Role.hbm.xml
...
  <set name="users" table="user_role" inverse="true" cascade="save-update">
       <key column="role_id" />
       <many-to-many class="dgut.ke.blog.model.User" column="user_id"/>
    </set>
...
  注意:在Role.hbm.xml配置文件中设置inverse="true"属性,因而User和Role两者之间的关系通过
User来进行维护
.

保存实体情况:
  ...
  User user = (User)session.get(User.class, "2c9ab2d514af5a3d0114af5a41f90001");
  Role role = new Role();
  user.getRoles().add(role);
  session.save(role); 
  ...
在运行的过程中,会执行以下语句
Hibernate: select user0_.id as id0_0_, user0_.name as name0_0_, user0_.password as password0_0_ from user user0_ where user0_.id=?
Hibernate: select roles0_.user_id as user1_1_, roles0_.role_id as role2_1_, role1_.id as id4_0_ from user_role roles0_ left outer join blog.role role1_ on roles0_.role_id=role1_.id where roles0_.user_id=?
Hibernate: insert into blog.role (id) values (?)
Hibernate: insert into user_role (user_id, role_id) values (?, ?)
可以看到.上面的第四条语句维护两个对象之间的关系.如果将上面的user.getRoles().add(role);改成
role.getUsers().add)(user);由于Role对象不是关系的维护方,在运行时就不会产生第四条语句,相应的
在第三方表user_role也会不插入相应的记录.

删除关联关系
...
  User user = (User)session.get(User.class, "2c9ab2d514af5a3d0114af5a41f90001");
  Role role = (Role)session.get(Role.class, "2c9ab2d514af97a60114af97abc60001");
  user.getRoles().remove(role);
...
上面的代码的执行,不会删除任何JAVA对象,只会删除对象之间的关联关系.控制台输出的语句如下
......
Hibernate: delete from user_role where user_id=? and role_id=?
同样,如果将user.getRoles().remove(role);语句改换成role.getUsers().remove(user);则控制台
不会发出以delete语句.关联关系不会被删除.

  



posted on 2007-08-29 11:40 Ke 阅读(338) 评论(1)  编辑  收藏 所属分类: hibernate

FeedBack:
# re: 映射中的inverse 2008-09-20 17:52 helloklzs
怎么你举的例子中,一对多与多对多关系inverse的判断不太一样,如何来判断呢?

像你的第一个实例:一对多 inverse为false怎么是由message维护呢?它不是在user.hbm.xml里配制的吗?我觉得为true时由message来维护才是,不是因为inverse为true时,维护权由对方吗?
既然这里为true,维护权就应该在对方,即在message而不应该在user那方;
而你举的第二例子:多对多的,role.hbm.xml里设置了true就成了user方维护,这个理解;但这样一来,一对多与多对多inverse的判断就不一样了,如何解决呢?  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: