单向多对多关系映射

多对多其实是个很复杂的关系,hibernate在进行处理的时候借助中间表或者中间类。中间表是在映射文件的关联标签(比如集合标签<set>)中由table属性指定的由hibernate自动生成的表,它只有两个字段,分别由<key>和<many-to-many>标签的table属性指定,作为外键分别用来指向关联双方表的主键。中间类就是把我们的中间表抽象生成一个实体类,在映射的时候分别和两个关联类构成一对多的关系,即演变成两个一对多来处理。

以下用中间表的例子来说明单向多对多关系映射:运动员(player)与角色(role)就是典型的多对多关系。

首先创建player,role类分别对应的表格:sxt_hibernate_player,sxt_hibernate_role,和中间表sxt_hibernate_player_role(在MySQL环境中)代码如下:

createtablesxt_hibernate_player(

idint(11)notnullauto_increatement,

namevarchar(16),

primarykey(id)

)ENGINE=InnoDBDEFAULTCHARSET=gbk;

createtablesxt_hibernate_role(

idint(11)notnullauto_increatement,

namevarchar(16),

primarykey(id)

)ENGINE=InnoDBDEFAULTCHARSET=gbk;

createtablesxt_hibernate_player_role(

player_idint(11),

role_idint(11)

)ENGINE=InnoDBDEFAULTCHARSET=gbk;

Player实体类:

publicclassPlayer{

privateIntegerid;

privateStringname;

privateSet<Role>roles;

//...省去一系列的setter.getter方法

@Override

publicStringtoString(){

return"Player:"+name;

}

}

Role实体类:

publicclassRole{

privateIntegerid;

privateStringname;

//...省去一系列的setter.getter方法

@Override

publicStringtoString(){

return"Role:"+name;

}

}

映射文件:

Role.hbm.xml

<classname="com.sxt.hibernate.many2many.entity.Role"table="sxt_hibernate_role">

<idname="id"length="4">

<generatorclass="native"></generator>

</id>

<propertyname="name"length="10"></property>

</class>

Player.hbm.xml

<classname="com.sxt.hibernate.many2many.entity.Player"table="sxt_hibernate_player">

<idname="id"length="4">

<generatorclass="native"></generator>

</id>

<propertyname="name"length="10"></property>

<!--table="sxt_hibernate_user_role"含义,用来指定中间表-->

<setname="roles"table="sxt_hibernate_player_role"cascade="save-update">

<!--<keycolumn="user_id">含义,指定中间表中用来指向本表的外键-->

<keycolumn="player_id"></key>

<!--column含义,用来指定中间表中用来指向另一端表的外键-->

<many-to-manyclass="com.sxt.hibernate.many2many.entity.Role"column="role_id"></many-to-many>

</set>

</class>

测试类Test:

publicclassTest{

publicstaticvoidmain(String[]args){

Sessionsession=HibernateUtils.getSession();

Transactiont=session.beginTransaction();

try{

/**

*测试插入数据

*/

Rolerole1=newRole();

role1.setName("后卫");

Rolerole2=newRole();

role2.setName("前锋");

Rolerole3=newRole();

role3.setName("中锋");

Playerplayer1=newPlayer();

player1.setName("姚明");

Set<Role>roles1=newHashSet<Role>();

roles1.add(role3);

player1.setRoles(roles1);

Playerplayer2=newPlayer();

player2.setName("詹姆斯");

Set<Role>roles2=newHashSet<Role>();

roles2.add(role1);

roles2.add(role2);

roles2.add(role3);

player2.setRoles(roles2);

//能正确保存.每保存player后,都要级联保存它的role,并且级联插入中间表记录.

session.save(player1);

session.save(player2);*/

/**

*测试加载数据

*/

Playerplayer=(Player)session.load(Player.class,1);

System.out.println(player);

for(Iterator<Role>iterator=player.getRoles().iterator();iterator.hasNext();){

System.out.println(iterator.next());

}

t.commit();

}catch(HibernateExceptione){

e.printStackTrace();

t.rollback();

}finally{

HibernateUtils.closeSession(session);

}

}

}

相关推荐