欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate中多对多关系的配置以及增删改操作

程序员文章站 2022-04-24 10:36:12
...

两张表:Performer(演员)和Role(角色)

配置分别如下(其实配置一方即可):

演员类的配置

 <hibernate-mapping package="com.dimples.dao">
    	<class name="Performer" table="performer">
    		<id name="id" column="id">
    			<generator class="native"></generator>
    		</id>
    		<property name="name" column="name"></property>
    		<property name="address" column="address"></property>
    		
    		<set name="roles" table="performer_role" inverse="true" cascade="delete">    //name属性是跑不掉的不多说,table是在指定对应中间表的名字
    			<key column="performer_id"></key>    //这个column是在指定performer表在中间表对应的字段名
    			<many-to-many class="Role" column="role_id"/>    //class配置类以后可以get相关从表的名字,column在指定那个从表在中间表上对应字段的名字
    		</set>
    	</class>
    </hibernate-mapping>

角色类的配置

 <hibernate-mapping package="com.dimples.dao">
    	<class name="Role" table="role">
    		<id name="id" column="id">
    			<generator class="native"></generator>
    		</id>
    		<property name="name" column="name"></property>
    		<property name="movie" column="movie"></property>
    		
    		<set name="performers" table="performer_role">
    			<key column="role_id"></key>
    			<many-to-many class="Performer" column="performer_id"/>
    		</set>
    	</class>
    </hibernate-mapping>



多对多的增删改操作:

新增两个performer和三个role,performer1 对应着 role1、role2。performer2 对应着 role2、 role3.

@org.junit.Test
	public void test() {
		Session session = SessionFactoryUtils.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		//new对象
		Performer p1 = new Performer();
		Performer p2 = new Performer();
		
		Role role1 = new Role();
		Role role2 = new Role();
		Role role3 = new Role();
		
		//初始化各个对象
		p1.setName("人物1");
		p2.setName("人物2");
		role1.setName("角色1");
		role2.setName("角色2");
		role3.setName("角色3");
		
		//添加好他们之间的关系
		p1.getRoles().add(role1);
		p1.getRoles().add(role2);
		p2.getRoles().add(role2);
		p2.getRoles().add(role3);
		role1.getPerformers().add(p1);
		role2.getPerformers().add(p1);
		role2.getPerformers().add(p2);
		role3.getPerformers().add(p2);
		
		session.save(p1);
		session.save(p2);
		session.save(role1);
		session.save(role2);
		session.save(role3);
		
		tx.commit();
	}

这里注意了,因为我上面在Performer.hbm.xml中配置了inverse=true,让performer放弃维护关联关系的权利(在另一个xml里配置也行,只要一方放弃即可),所以能执行成功。如果两方都不配,那么保存的时候会报错,ID冲突,因为两张表在插入记录的时候都会去维护中间那个表,大家都生成,所以会出问题,所以记得要让一方放弃维护关联关系。


多对多更新

中间表存的只有两表记录对应的ID,但真正更新你不可能更新ID的,所以更新根本不受影响,就是单表更新。


多对多删除

三种情况(一方配了cascade=delete,两方都配了cascade=delete,都没配cascade=delete)

都没配的时候,删除数据时如果有相关关联数据存在,那么删除失败,报有约束不能执行语句的错误。

两方都配置是禁止使用的,因为会关联删除很多数据,太危险。

一方配置了的情况如下:

@org.junit.Test
	public void test2(){
		Session session = SessionFactoryUtils.getSessionFactory().getCurrentSession();
		Transaction tx = session.beginTransaction();
		Performer p = session.get(Performer.class, Integer.parseInt("1"));
		session.delete(p);    //此处已经在performer那一方配置了级联删除
		tx.commit();
	}
结果就是这个performer以及这个performer对应的所有role全部被删除,除此之外中间表中跟performer和相关role沾边的所有记录全部被删除,慎用!