近来使用hbernate越多,越觉得他的关系映射不简单。
如果用错映射策略,很可能导致表设计的修改。
下面我们分析一下他的多对多关系,
其唯一的用途就是维护关系数据库中两张表或者多张表之间的关系
如最典型的权限设计时,基于组-角色-用户的设计,
三者之间分别为多对多的关系,换言之,组可以有多个角色,角色也可以属于多个组。
group:
properties:id,name,description,roleSet,userSet
role
properties:id,name,description,groupset
多对多关系需要一个中间表来维护(group_role)
group.hbm.xml
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 < 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 >
我们大都以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.