本来是准备一口气把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();
}
}
本文介绍Hibernate框架中如何实现多对多关系的映射,包括创建表结构、定义实体类、配置映射文件及编写测试代码。
3829

被折叠的 条评论
为什么被折叠?



