今天来说说Hibernate中的多对多关联映射,多对多关联映射涉及到单向映射和双向映射2种。
首先举个多对多关联例子:用户User和角色Role,一个用户可以属于多个角色,一个角色可以有多个用户。这就是典型的多对多关联的例子。而单向关联映射则是只能由A端去操作B端,B端不能操作A端的数据。而双向关联映射则是A,B两端都可以操作另一端的数据。
先说单向关联映射,实体类如下:
[java] view plain
<embed id="ZeroClipboardMovie_1" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_1" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=1&width=16&height=16" wmode="transparent" align="middle" width="16" height="16">
-
<span style=
"font-size:18px;"
/**
- 学生类
- @author Longxuan
-
*/
-
public
class
User {
-
private
int
id;
-
private
String name;
-
private
Set<Role> roles;
-
//此处省略get和set方法
-
}
-
/**
- 班级类
- @author Longxuan
-
*/
-
public
class
Role {
- private
int
id;
-
private
String name;
-
//此处省略get和set方法
-
}
-
</span>
映射文件:
[html] view plain
<embed id="ZeroClipboardMovie_2" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_2" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=2&width=16&height=16" wmode="transparent" align="middle" width="16" height="16">
-
<
span
style
=
"font-size:18px;"
<?
xml
version
=
"1.0"
?>
-
<!DOCTYPE hibernate-mapping PUBLIC
-
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
-
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
-
<
hibernate-mapping
package
=
"com.bjpowernode.hibernate"
-
<
class
name
=
"User"
table
=
"t_user"
-
<
id
name
=
"id"
-
<
generator
class
=
"native"
/>
-
</
id
-
<
property
name
=
"name"
/>
- <
set
name
=
"roles"
table
=
"t_user_role"
>
- <
key
column
=
"user_id"
>
</
key
>
- <
many-to-many
class
=
"Role"
column
=
"roleid"
>
</
many-to-many
>
- </
set
>
- </
class
>
- <
class
name
=
"Role"
table
=
"t_role"
>
- <
id
name
=
"id"
>
- <
generator
class
=
"native"
/>
- </
id
>
- <
property
name
=
"name"
/>
- </
class
>
- </
hibernate-mapping
>
</
span
>
User类有Role的Set集合,而且映射文件中也设置了Set标签和many-to-many标签,所以可以通过User操作Role,但是却不能从Role中操作数据。多对多的关系维护用到了第三张表t_user_role。它存放了User和Role的主键。
从上面的单向多对多关联映射来看,我可以查某个用户属于哪些角色,但是却不能查某个角色中有哪下用户。所以为了解决这个问题,我们采用双向关联映射。
其实说白了,双向关联映射就是在2端都设置一下映射关系。即在Role中同样添加User的set集合:
[java] view plain
<embed id="ZeroClipboardMovie_3" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_3" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=3&width=16&height=16" wmode="transparent" align="middle" width="16" height="16">
-
<span style=
"font-size:18px;"
/**
- 班级类
- @author Longxuan
-
*/
-
public
class
Role {
-
private
int
id;
-
private
String name;
-
private
Set<User> users;
-
//此处省略get和set方法
-
}
-
</span>
映射文件中的Role部分也要做相应的修改:
[html] view plain
<embed id="ZeroClipboardMovie_4" src="http://static.blog.csdn.net/scripts/ZeroClipboard/ZeroClipboard.swf" loop="false" menu="false" quality="best" bgcolor="#ffffff" name="ZeroClipboardMovie_4" allowscriptaccess="always" allowfullscreen="false" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" flashvars="id=4&width=16&height=16" wmode="transparent" align="middle" width="16" height="16">
-
<
span
style
=
"font-size:18px;"
<
class
name
=
"Role"
table
=
"t_role"
-
<
id
name
=
"id"
-
<
generator
class
=
"native"
/>
-
</
id
-
<
property
name
=
"name"
/>
-
<
set
name
=
"users"
table
=
"t_user_role"
-
<
key
column
=
"roleid"
</
key
-
<
many-to-many
class
=
"User"
column
=
"user_id"
</
many-to-many
-
</
set
-
</
class
>
</
span
>
值得注意的是,配置文件中的table和两个column,都必须是一致的。否则肯定会出错的。如果表名不一样了,那么就会生成2张中间表,一张有User维护,一张有Role。因为它变成了2个多对多单向关联映射。如果列名不一致了,就会出列来。还是变成了2个多对多单向关联映射。同时数据也发生了冗余。
所以双向关联映射,一定要保证2端的映射关系都设置一致了。才能称之为“双向关联映射”。
网友评论