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,哈哈

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate是一个Java持久化框架,它能够将Java对象映射到数据库中的表格,同时支持各种关系数据库,如MySQL、Oracle等。在Hibernate中,对于一对一、一对多和多对多的关系,我们可以通过以下方式进行映射。 一对一关系:在Hibernate中,可以通过主键关联和外键关联来实现一对一关系的映射。主键关联是指两个实体之间的关联通过主键来进行,可以使用@PrimaryKeyJoinColumn注解将两个实体关联起来。外键关联是指通过一个实体引用另一个实体的主键作为外键,使用@JoinColumn注解来指定外键属性。 一对多关系:在Hibernate中,一对多关系通常通过外键关联来实现。在一的一方,使用@OneToMany注解来定义一对多关系,同时使用@JoinColumn注解指定外键属性。在多的一方,使用@ManyToOne注解来定义多对一关系,并使用@JoinColumn注解指定外键属性。 多对多关系:在Hibernate中,多对多关系通常通过中间表来实现。在多对多的两个实体中,使用@ManyToMany注解来定义多对多关系。同时,需要在中间表中创建两个外键,分别与两个实体的主键关联,并使用@JoinTable注解来指定中间表的表名和两个外键的列名。 总结:通过Hibernate的注解方式,可以方便地实现一对一、一对多和多对多关系的映射。通过合理地使用注解,可以减少编写映射文件的工作量,提高开发效率。同时,Hibernate还提供了在运行时自动生成表结构的功能,可以根据Java实体类来动态创建或更新对应的数据库表格,从而提高系统的可维护性和灵活性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值