当前位置: 代码迷 >> Web前端 >> 单向多对多关系照射
  详细解决方案

单向多对多关系照射

热度:300   发布时间:2012-11-06 14:07:00.0
单向多对多关系映射
          多对多其实是个很复杂的关系,hibernate在进行处理的时候借助中间表或者中间类。中间表是在映射文件的关联标签(比如集合标签<set>)中由table属性指定的由hibernate自动生成的表,它只有两个字段,分别由<key>和<many-to-many>标签的table属性指定,作为外键分别用来指向关联双方表的主键。中间类就是把我们的中间表抽象生成一个实体类,在映射的时候分别和两个关联类构成一对多的关系,即演变成两个一对多来处理。
          以下用中间表的例子来说明单向多对多关系映射:运动员(player)与角色(role)就是典型的多对多关系。
          首先创建player,role类分别对应的表格:sxt_hibernate_player,sxt_hibernate_role,和中间表sxt_hibernate_player_role(在MySQL环境中)代码如下:

          create table sxt_hibernate_player(
                      id    int(11)  not null auto_increatement,
                      name  varchar(16),
                      primary key(id)
         )ENGINE=InnoDB DEFAULT CHARSET=gbk;

         create table sxt_hibernate_role(
                      id    int(11)  not null auto_increatement,
                      name  varchar(16),
                      primary key(id)
         )ENGINE=InnoDB DEFAULT CHARSET=gbk;

         create table sxt_hibernate_player_role(
                      player_id    int(11),
                      role_id      int(11)
         )ENGINE=InnoDB DEFAULT CHARSET=gbk;

              Player实体类:
          
              public class Player {

                           private Integer id;
                           private String name;
                           private Set<Role> roles;
                           //...省去一系列的setter.getter方法
                               @Override
                           public String toString() {
                           return "Player:" + name;
                           }
            }
             Role实体类:
       
             public class Role {

                            private Integer id;
                            private String name;
                            //...省去一系列的setter.getter方法
                                 @Override
                            public String toString() {
                            return "Role:" + name;
                            }
           }
             映射文件:

             Role.hbm.xml
  <class name="com.sxt.hibernate.many2many.entity.Role" table="sxt_hibernate_role">
    <id name="id" length="4">
      <generator class="native"></generator>
    </id>
    <property name="name" length="10"></property>
  </class>
   Player.hbm.xml
  <class name="com.sxt.hibernate.many2many.entity.Player" table="sxt_hibernate_player">
    <id name="id" length="4">
      <generator class="native"></generator>
    </id>
    <property name="name" length="10"></property>
    <!--table="sxt_hibernate_user_role"含义,用来指定中间表    -->
    <set name="roles" table="sxt_hibernate_player_role" cascade="save-update">
      <!--<key column="user_id">含义,指定中间表中用来指向本表的外键    -->
      <key column="player_id"></key>
      <!-- column含义,用来指定中间表中用来指向另一端表的外键 -->
      <many-to-many class="com.sxt.hibernate.many2many.entity.Role" column="role_id"></many-to-many>
    </set>
  </class>

              测试类Test:

              public class Test{

              public static void main(String[] args) {
    Session session = HibernateUtils.getSession();
    Transaction t = session.beginTransaction();
    try {
      /**
        * 测试插入数据
         */
      Role role1=new Role();
      role1.setName("后卫");
       
      Role role2=new Role();
      role2.setName("前锋");
       
      Role role3=new Role();
      role3.setName("中锋");
       
      Player player1=new Player();
      player1.setName("姚明");
      Set<Role> roles1=new HashSet<Role>();
      roles1.add(role3);
      player1.setRoles(roles1);
       
      Player player2=new Player();
      player2.setName("詹姆斯");
      Set<Role> roles2=new HashSet<Role>();
      roles2.add(role1);
      roles2.add(role2);
      roles2.add(role3);
      player2.setRoles(roles2);
      //能正确保存.每保存player后,都要级联保存它的role,并且级联插入中间表记录.
      session.save(player1);
      session.save(player2);*/
       
      /**
        * 测试加载数据
        */
      Player player=(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 (HibernateException e) {
      e.printStackTrace();
      t.rollback();
    } finally {
      HibernateUtils.closeSession(session);
    }
  }
}
  相关解决方案