hibernate的级联---many-to-many

本文介绍Hibernate框架中如何实现多对多关系的映射,包括创建表结构、定义实体类、配置映射文件及编写测试代码。

本来是准备一口气把hibernate的级联关系写完的,但是中途老大让讲一下mybatis,只好转头把mybatis整理了一下,今天刚好有空,就把hibernate接着写完吧。

多对多的关系,在实际应用中也用得挺多,前面说过,数据库默认的表关系只有多和一,所以处理多对多的表关系,需要建立一个中间表,将多对多转化为两个一对多。当然,在hibernate的关联关系中,多对多和一对多还是有些区别的,在这里先创建表。

Emp(员工)表和Pro(项目)表,两个表都只需要两个简单的字段就可以了。

下面是sql:

create table emp(
emp_id      number primary key
,emp_name   varchar2(50)
);

create table pro(
pro_id    number primary key
,pro_name varchar2(50)
);


create table r_emp_pro(
 r_emp_id number
 ,r_pro_id number
 ,primary key(r_emp_id,r_pro_id)
);


然后是对应的实体,只需要两个表对应的实体就可以了,中间表主要是用来做关联用的,并不需要创建实体类。

public class Pro {

	private Integer id;
	private String name;
	private Set<Emp> emps = new HashSet<Emp>();
}

public class Emp {

    private Integer id;
    private String name;
    private Set<Pro> pros = new HashSet<Pro>();
}

然后是映射文件:

这里依然用的是set标签,但是注意标签中的书写和many-to-one不同,这里set标签中有“table”属性,对应的值是中间表的表名,下面key的值对应的是中间表中本表对应的字段,

而many-to-many标签中class对应set集合也就是关联表的实体,column的值依然是中间表中的字段,不过是关联表对应的字段。


cascade属性仍旧不推荐使用,除非有特殊需要,当然,如果是与spring结合,在spring中配置事务处理,那么就必须要拿掉了。

<hibernate-mapping package="com.entity">

	<class name="Emp" table="EMP">
		<id name="id" type="integer" column="EMP_ID" >
			<generator class="increment"/>
		</id>
		<property name="name" column="EMP_NAME"></property>
		<set name="pros" table="R_EMP_PRO" cascade="all">
			<key column="R_EMP_ID"></key>
			<many-to-many class="Pro" column="R_PRO_ID"></many-to-many>
		</set>
	</class>
</hibernate-mapping>



<hibernate-mapping package="com.entity">

    <class name="Pro" table="PRO">
        <id name="id" type="integer" column="PRO_ID" >
            <generator class="increment"/>
        </id>
        <property name="name" column="PRO_NAME"></property>
        <set name="emps" table="R_EMP_PRO" cascade="all">
            <key column="R_PRO_ID"></key>
            <many-to-many class="Emp" column="R_EMP_ID"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

下面是测试类:

package com.test;

import java.util.Iterator;
import java.util.Set;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

import com.entity.Emp;
import com.entity.Pro;

public class TestMany2Many {
	public static void main(String[] args) {
		TestMany2Many test = new TestMany2Many();
		test.query();
	}

	public void add() {
		Configuration config = new Configuration().configure();
		SessionFactory factory = config.buildSessionFactory();
		Session session = factory.openSession();
		Emp emp = new Emp();
		emp.setName("张三");
		Pro pro1 = new Pro();
		Pro pro2 = new Pro();
		Pro pro3 = new Pro();
		pro1.setName("aaa");
		pro2.setName("bbb");
		pro3.setName("ccc");// 设置id有自增,最好不要自己写id;
		emp.getPros().add(pro1);
		emp.getPros().add(pro2);
		emp.getPros().add(pro3);//这里因为设置了cascade="all",所以可以执行关联保存,通常并不需要这种用法,下同
                Transaction tr = session.beginTransaction();
		session.save(emp);
		tr.commit();
		session.close();
		factory.close();
	 }
	        public void query(){
		 Configuration config = new Configuration().configure();
		 SessionFactory factory = config.buildSessionFactory();
		Session session = factory.openSession();
		 Emp emp = (Emp) session.get(Emp.class, 1);
		 Set<Pro> pros = emp.getPros();
		 Iterator<Pro> iter = pros.iterator();
		while(iter.hasNext()){
			Pro pro = iter.next();
			System.out.println(pro.getName());
		}
		session.close();
		factory.close();
	}
	
	public void remove(){
		Configuration config = new Configuration().configure();
		SessionFactory factory = config.buildSessionFactory();
		Session session = factory.openSession();
		Emp emp = (Emp) session.get(Emp.class, 2);
		Pro pro = (Pro) session.get(Pro.class, 5);
		emp.getPros().remove(pro);
		Transaction tr = session.beginTransaction();
		session.update(emp);
		tr.commit();
		session.close();
		factory.close();		
	}

}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值