Hibernate框架之双向多对多关系映射
昨天跟大家分享了Hibernate中单向的一对多、单向多对一、双向一对多的映射关系,今天跟大家分享下在Hibernate中双向的多对多的映射关系
这次我们以项目和员工举个栗子,因为大家可以想象得到,在真实的环境下,一个项目肯定是对应着多个员工的,这毫无疑问,
那么同时,一个比较牛员工也能同时参与多个项目的开发,这就体现了双向多对多的关系。
首先呢,我们得弄清楚在底层数据库中表与表之间的关系,我们创建一个员工表(Employee)和项目表(Project)毫无疑问,那么我们要怎么体现出多对多的关系呢?
当然有很多种方法,这里我以单独提出一张关系表为例,也就是说,我单独创建一张表来保存员工和项目的关系,具体的实体类如下
Employee
package entity; import java.util.HashSet; import java.util.Set; /* * 员工表 * */ public class Employee { private Integer empid;//员工编号 private String empname;//员工名称 //准备一个项目集合 private Set<Project> pros=new HashSet<Project>(); public Set<Project> getPros() { return pros; } public void setPros(Set<Project> pros) { this.pros = pros; } public Employee(String empname) { super(); this.empname = empname; } public Employee(Integer empid, String empname) { this.empid = empid; this.empname = empname; } public Employee() { } public Integer getEmpid() { return empid; } public void setEmpid(Integer empid) { this.empid = empid; } public String getEmpname() { return empname; } public void setEmpname(String empname) { this.empname = empname; } }
Proemp
package entity; /* * 表示员工和项目相关联的表 * */ public class Proemp { private Integer rproid;//项目编号 private Integer rempid;//员工编号 public Proemp(Integer rproid, Integer rempid) { this.rproid = rproid; this.rempid = rempid; } public Proemp() { } public Integer getRproid() { return rproid; } public void setRproid(Integer rproid) { this.rproid = rproid; } public Integer getRempid() { return rempid; } public void setRempid(Integer rempid) { this.rempid = rempid; } }
Project
package entity; import java.util.HashSet; import java.util.Set; /* * 项目表 * */ public class Project { private Integer proid;//项目编号 private String proname;//项目名称 //声明员工集合 private Set<Employee> emps=new HashSet<Employee>(); public Set<Employee> getEmps() { return emps; } public void setEmps(Set<Employee> emps) { this.emps = emps; } public Project(String proname) { this.proname = proname; } public Integer getProid() { return proid; } public void setProid(Integer proid) { this.proid = proid; } public String getProname() { return proname; } public void setProname(String proname) { this.proname = proname; } public Project(Integer proid, String proname) { this.proid = proid; this.proname = proname; } public Project() { } }
这样我们的实体类就全部创建完毕,接下来我们就可以配置映射关系文件了,既然是双向的多对多的关系,那么肯定少不了<set></set>标签
Project.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity"> <class name="Project" table="project"> <id name="proid" column="proid"> <generator class="increment" /> </id> <property name="proname" type="string" column="proname" /> <!-- 配置多对多的关联关系 设置级联属性--> <set name="emps" table="proemp" cascade="all"> <key column="rproid"></key> <many-to-many class="entity.Employee" column="rempid"></many-to-many> </set> </class> </hibernate-mapping>
Employee.hbm.xml
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="entity"> <class name="Employee" table="Employee"> <id name="empid" column="empid"> <generator class="increment" /> </id> <property name="empname" type="string" column="empname" /> <!-- 配置多对多的关联配置 设置反转属性,让项目管理关系 --> <set name="pros" table="proemp" inverse="true"> <key column="rempid"></key> <many-to-many class="entity.Project" column="rproid"></many-to-many> </set> </class> </hibernate-mapping>
经过以上的步骤,整个配置过程就全部完成了,当然同学们别忘记了在Hibernate配置文件(大配置)中添加对两个映射文件(小配置)的引用
测试类
package test; import org.hibernate.Session; import org.hibernate.Transaction; import util.HibernateUtil; import entity.Employee; import entity.Project; public class Test { public static void main(String[] args) { /* * 多对多的关联关系配置 * 同时配置了Project和Employee之间双向的多对多的关联关系 * 关联关系由Project方维护,并且在Project方设置了级联属性 * */ //获取Session Session session=HibernateUtil.currentSession(); //开启事务 Transaction tx = session.beginTransaction(); //构建两个项目 Project pro1=new Project("项目一"); Project pro2=new Project("项目二"); //构建多个员工 Employee emp1=new Employee("巴黎的雨季"); Employee emp2=new Employee("盛夏的果实"); Employee emp3=new Employee("听风"); Employee emp4=new Employee("黎明前的黑暗"); //将员工123加入项目一 pro1.getEmps().add(emp1); pro1.getEmps().add(emp2); pro1.getEmps().add(emp3); //将员工234加入项目二 pro2.getEmps().add(emp2); pro2.getEmps().add(emp3); pro2.getEmps().add(emp4); //保存项目一和项目二 session.save(pro1); session.save(pro2); //提交事务 tx.commit(); //关闭连接 HibernateUtil.closeSession(); } }
以上代码,我们可以发现我们仅仅保存了项目,并没有手动的添加保存员工的代码,也没有手动添加保存员工和项目之间关系的表的代码
我们可以看到Hibernate帮我们生成的sql
Hibernate很智能的通过配置文件帮我们生成了我们需要的sql,这就是面向对象思想的体现,我们自始至终都只关注了项目这个对象就完成了我们所需要的操作
我们可以看看数据库中的记录
以上就是如何去配置双向多对多的映射关系的代码和解释了。希望对大家有点用~~