实现:在数据库中添加中间表来维护两个表的关联关联。
在映射文件中使用<set>标签管理,并在每一个持久化类中添加对方的集合
以员工和项目为背景来看一下具体实现:
一个员工可以参加多个项目,并且一个项目可以有多个员工,这个就是一个多对多映射。
1.如何建立员工和项目之间的关联关系,通过第三个表来实现。
首先来看一下数据库结构:
--员工表 CREATE TABLE EMPLOYEE ( ID NUMBER(10) NOT NULL, EMNAME VARCHAR2(255 CHAR), EMSEX VARCHAR2(2 CHAR), PRIMARY KEY(ID) ) --项目表 CREATE TABLE PROJECT ( ID NUMBER(10) NOT NULL, PRNAME VARCHAR2(255 CHAR), PRIMARY KEY(ID) ) --员工项目关联关系表 CREATE TABLE PROEMP ( EMP_ID NUMBER(10) NOT NULL, PRO_ID NUMBER(10) NOT NULL, PRIMARY KEY(EMP_ID,PRO_ID) ) --该表的两个外键 ALTER TABLE SUNYQ.PROEMP ADD (CONSTRAINT FK_AAJJDHEGP8CRARVM34YRR639A FOREIGN KEY (PRO_ID) REFERENCES SUNYQ.PROJECT (ID), CONSTRAINT FK_4RRTN484UGR027VMDDSPFGFIU FOREIGN KEY (EMP_ID) REFERENCES SUNYQ.EMPLOYEE (ID));
2.持久化类
Employee中持有Project的set集合
... private int emid; private String emname; private String emsex; private Set<Project> proSet = new HashSet<Project>(); public int getEmid() { return emid; } public void setEmid(int emid) { this.emid = emid; } ...
Project中持有Employee的set集合
... private int prid; private String prname; private Set<Employee> empSet = new HashSet<Employee>(); public Set<Employee> getEmpSet() { return empSet; } public void setEmpSet(Set<Employee> empSet) { this.empSet = empSet; } ...
3.映射文件
映射文件需要仔细的说明一下:
①Employee.hbm.xml
在Employee持久化类中包含的是Project的set集合:proSet
<set>标签:name就是该对象porSet,table就是关联关系表名叫proemp
<key column="emp_id"/>表示:在proemp表中对应employee表的外键。
<many-to-many />标签:实际的映射关系,Employee与Project的映射关系。
<hibernate-mapping> <class name="com.iteye.sunyq.hibernate.Employee" table="employee"> <id name="emid" type="integer"> <column name="id"></column> <generator class="native"></generator> </id> <property name="emname" type="string"> <column name="emname"></column> </property> <property name="emsex" type="string" > <column name="emsex" length="2"></column> </property> <!-- name:持久化类中set集合的名称 table:第三方表名 --> <set name="proSet" table="proemp"> <!-- 在第三表里面查询emp_id值相应的employee记录 --> <key column="emp_id"></key> <!--对Project表中查找pro_id值相就的project记录 --> <many-to-many class="com.iteye.sunyq.hibernate.Project" column="pro_id"></many-to-many> </set> </class> </hibernate-mapping>
②Project.hbm.xml
在Project.java中包含的是Employee的set集合:empSet
<set标签:name为该集合对象empSet,table为关联关系表名proemp
<key column="pro_id"/>标签:在proemp表中对应Project表的外键字段名
<many-to-many标签:实际的映射关系,与pro_id对应的emp_id的信息
<hibernate-mapping> <class name="com.iteye.sunyq.hibernate.Project" table="project"> <id name="prid" type="integer"> <column name="id"></column> <generator class="native"></generator> </id> <property name="prname" type="string"> <column name="prname"></column> </property> <set name="empSet" table="proemp"> <key column="pro_id"></key> <many-to-many class="com.iteye.sunyq.hibernate.Employee" column="emp_id"></many-to-many> </set> </class> </hibernate-mapping>
4.测试类
Session session = HibernateUtil.getSession(); Transaction transaction = session.beginTransaction(); Project p1 = new Project("项目一"); Project p2 = new Project("项目二"); Employee e1 = new Employee("小王","男"); Employee e2 = new Employee("小张","女"); p1.getEmpSet().add(e1);//给项目1添加员工1 p1.getEmpSet().add(e2);//给项目1添加员工2 p2.getEmpSet().add(e1);//给项目2添加员工1 session.save(e1); session.save(e2); session.save(p1); session.save(p2); transaction.commit(); HibernateUtil.closeSession(session);
查看一下执行sql:
在看一下数据库情况:
employee
project
proemp
5.为了提高性能,可以设置inverse来指定维护方,和cascase级联关系方便维护。