hibernate关系映射之多对多
近来使用hbernate越多,越觉得他的关系映射不简单。
如果用错映射策略,很可能导致表设计的修改。
下面我们分析一下他的多对多关系,
其唯一的用途就是维护关系数据库中两张表或者多张表之间的关系
如最典型的权限设计时,基于组-角色-用户的设计,
三者之间分别为多对多的关系,换言之,组可以有多个角色,角色也可以属于多个组。
group:
properties:id,name,description,roleSet,userSet
role
properties:id,name,description,groupset
多对多关系需要一个中间表来维护(group_role)
group.hbm.xml
1
<
hibernate-mapping
>
2
<
class
name
="model.GroupInfo"
table
="GROUP_INFO"
lazy
="false"
>
3
<
id
name
="id"
type
="long"
column
="ID"
>
4
<
generator
class
="native"
/>
5
</
id
>
6
<
property
name
="name"
column
="name"
length
="20"
type
="string"
/>
7
<
property
name
="description"
column
="description"
type
="string"
/>
8
<
set
name
="userSet"
table
="group_user"
cascade
="save-update"
lazy
="true"
>
9
<
key
column
="group_id"
/>
10
<
many-to-many
column
="user_id"
class
="com.essp.fable.model.UserInfo"
/>
11
</
set
>
12
<
set
name
="roleSet"
table
="group_role"
cascade
="save-update"
lazy
="true"
>
13
<
key
column
="group_id"
/>
14
<
many-to-many
column
="role_id"
class
="com.essp.fable.model.RoleInfo"
/>
15
</
set
>
16
</
class
>
17
</
hibernate-mapping
>
role.hbm.xml
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
<
hibernate-mapping
>
2
<
class
name
="model.RoleInfo"
table
="ROLE_INFO"
lazy
="false"
>
3
<
id
name
="id"
type
="long"
column
="ID"
>
4
<
generator
class
="native"
/>
5
</
id
>
6
<
property
name
="name"
column
="name"
length
="20"
type
="string"
/>
7
<
set
name
="groupSet"
table
="group_role"
cascade
="save-update"
inverse
="true"
lazy
="true"
>
8
<
key
column
="role_id"
/>
9
<
many-to-many
column
="group_id"
class
="com.essp.fable.model.GroupInfo"
/>
10
</
set
>
11
</
class
>
12
</
hibernate-mapping
>
2
3
4
5
6
7
8
9
10
11
12
我们大都以set集合来实现他们的映射关系,配置xml的时候,最重的几个属性就是 cascade 和 inverse ,
cascade翻译为 小瀑布, 喷流,在这里表示对象间的级联关系,可以分别取值 为all,none,save-update,delete,all-delete-orphan,delete-orphan
cascade属性并不是多对多关系一定要用的,有了它只是让我们在插入或删除对像时更方便一些,只要在cascade的源头上插入或是删除,所有cascade的关系就会被自己动的插入或是删除。
为了能正确的cascade,unsaved-value是个很重要的属性。Hibernate通过这个属性来判断一个对象应该save还是update,如果这个对象的id是unsaved-value的话,那说明这个对象不是persistence object要save(insert);如果id是非unsaved-value的话,那说明这个对象是persistence object(数据库中已存在),只要update就行了。saveOrUpdate方法用的也是这个机制。
如unsaved-value="0",那当该值为0时,hibernate即判断其为未存储的对像,当执行saveOrUpdate时,实际执行的是save了。
In Hibernate3, it is no longer necessary to specify an unsaved-value explicitly. 不过在hibernate3中我们不需要显示的去指定他,hiberante会自动差别出该对像是否是新产生的对象。
inverse翻译为 倒转的, 反转的。他属于关系和对象的级联关系,默认时为false,,就是说关系的两端都来维护关系.如果一边设为true,那表示他们之间的关系由对方来维护。
比如上面的例子,我们设role的inverse为true,即他们的关系有group来维护。
GroupInfo group = new GroupInfo();
group.setName("admin");
RoleInfo role = new RoleInfo();
role.setName("acl");
group.addRole(role);
save(group);
执行完这些操作后,hibernate会自动保存group,role,若反之,则只会保存role.