hibernate映射 多对多 Many-to-Many

现在继上一章节的一对多的映射关系讲解后,今天来讲讲多对多的映射关系把,明白了一对多,多对多感觉还是比较容易的,需要理清楚其数据库关系图,那么你就拿下了它。

1:要保存多对多的关系,两张表是不够的,需要增加第三张表来表示这种关系,来看下面的数据库关系图

俩张中间表在数据库里面建好 ,实体类里面不需要建

为什么需要建中间表?

Users通过自己的主键在中间表中查询,因为是复合主键,所以查询到的记录有很多,而不是唯一的.

2、实体类和映射配置

Users.hbm.xml

 <class name="com.zking.Pojo.Users" table="USERS">
        <id name="uid" type="java.lang.String">
            <column name="UID" />
            <generator class="guid" />
        </id>
        <property name="uname" type="java.lang.String">
            <column name="UNAME" />
        </property>
        <!-- 配置角色集合 -->
          <!-- table  中间表  
               key column 中间表中指代本实体类的列  
               many-to-many column 中间表中指代集合对象的列 -->
        <set name="roleList" fetch="join" table="USERSROLES" lazy="false">
        <key column="uid" ></key>
        <many-to-many class="com.zking.Pojo.Roles" column="rid"></many-to-many>
        </set> 
    </class>

Roles.hbm.xml

<class name="com.zking.Pojo.Roles" table="ROLES">
        <id name="rid" type="java.lang.String">
            <column name="RID" />
            <generator class="guid" />
        </id>
        <property name="rname" type="java.lang.String">
            <column name="RNAME" />
        </property>
        <!-- 用户集合  都由roles维护-->
        <set name="UserList" table="USERSROLES"   cascade="save-update" inverse="true" fetch="join" >
        <key column="rid"></key> 
        <many-to-many class="com.zking.Pojo.Roles" column="uid"></many-to-many>
        </set>
        
        <!-- 菜单集合 --> 
        <set name="menuList"  table="ROLESMENU"  cascade="save-update"  inverse="true"  fetch="join"  > 
        <key column="rid"></key> 
        <many-to-many class="com.zking.Pojo.Menu" column="mid"></many-to-many>
        </set> 
    </class>

Menu.hbm.xml

 <class name="com.zking.Pojo.Menu" table="MENU">
        <id name="mid" type="java.lang.String">
            <column name="MID" />
            <generator class="guid" />
        </id>
        <property name="mname" type="java.lang.String">
            <column name="MNAME" />
        </property>
        
        <set name="mroleList" table="ROLESMENU"  fetch="join">
        <key column="mid"></key>
        <many-to-many class="com.zking.Pojo.Roles" column="rid"></many-to-many>
        </set>
        
    </class>

设置好三个表的映射关系 要设置好和中间表的关系

3、测试类 TestMany 因为还没有任何数据,就写一个增加的例子

@Test
	public void addtest() {
		Users u=new Users();
		//用户
		u.setUname("admin");
        //角色(权限)
		Roles r=new Roles();
		r.setRname("Admin");
		Roles r1=new Roles();
		r1.setRname("Super_Admin");
		//菜单
		Menu m=new Menu();
		m.setMname("用户管理");
		Menu m1=new Menu();
		m1.setMname("菜单管理");
		Menu m2=new Menu();
		m2.setMname("修改密码");
		Menu m3=new Menu();
		m3.setMname("角色管理");
	    //互设
		//用户赋予角色
		u.getRoleList().add(r);
		u.getRoleList().add(r1);
		//角色赋予用户
		r.getUserList().add(u);
		r1.getUserList().add(u);
		//角色加菜单
		r.getMenuList().add(m);
		r.getMenuList().add(m1);
		r.getMenuList().add(m2);
		r.getMenuList().add(m3);
		r1.getMenuList().add(m);
		r1.getMenuList().add(m1);
		r1.getMenuList().add(m2);
		r1.getMenuList().add(m3);
		//菜单对应角色
		m.getMroleList().add(r);
		m1.getMroleList().add(r);
		m2.getMroleList().add(r);
		m3.getMroleList().add(r);
		m.getMroleList().add(r1);
		m1.getMroleList().add(r1);
		m2.getMroleList().add(r1);
		m3.getMroleList().add(r1);
	    //保存
		//先保存user 才用关联性 在保存角色
		session.save(u);
		session.save(r1);
		session.save(r); 
	}

我在写的过程中报了一个TransientObjectException的异常

出现该错误的原因是在保存数据的时候只保存了从表中的数据,而在该情况下并没有使用级联。

解决方法:

所以我们应该同时保存主表的数据(与之对应的类)和从表的数据(与之对应的类)。

效果图:


中间表信息就不贴图了.

4、总结  

  双向多对多理解了之后就会发现很简单,但是在开始学的时候,会觉得里面很绕,所以一定清楚每一步是什么,重要的是理解为什么连接表需要设置成那样。理解了你就会很轻松的学会了这个双向多对多映射关系,你一定动手自己去实现一下,其中隐藏了很多BUG,需要自己去解决。如果不动手去实践,还是会很蒙蔽的,比如级联的设置,维护的设置。 

程序人生,一定要去好好的实践,祝你们都能找出bug,哈哈

猜你喜欢

转载自blog.csdn.net/qqqnzhky/article/details/82631521
今日推荐