映射中的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 閱讀(339)
評論(1) 編輯 收藏 所屬分類:
hibernate