今天跟大家分享下在Hibernate中雙向的多對多的映射關系
這次我們以項目和員工舉個栗子,因為大家可以想象得到,在真實的環境下,一個項目肯定是對應着多個員工的,這毫無疑問,
那么同時,一個比較牛員工也能同時參與多個項目的開發,這就體現了雙向多對多的關系。
首先呢,我們得弄清楚在底層數據庫中表與表之間的關系,我們創建一個員工表(Employee)和項目表(Project)毫無疑問,那么我們要怎么體現出多對多的關系呢?
當然有很多種方法,這里我以單獨提出一張關系表為例,也就是說,我單獨創建一張表來保存員工和項目的關系,具體的實體類如下
Employee
1 package entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /* 7 * 員工表 8 * */ 9 public class Employee { 10 private Integer empid;//員工編號 11 private String empname;//員工名稱 12 //准備一個項目集合 13 private Set<Project> pros=new HashSet<Project>(); 14 15 16 public Set<Project> getPros() { 17 return pros; 18 } 19 public void setPros(Set<Project> pros) { 20 this.pros = pros; 21 } 22 23 24 public Employee(String empname) { 25 super(); 26 this.empname = empname; 27 } 28 public Employee(Integer empid, String empname) { 29 this.empid = empid; 30 this.empname = empname; 31 } 32 public Employee() { 33 } 34 public Integer getEmpid() { 35 return empid; 36 } 37 public void setEmpid(Integer empid) { 38 this.empid = empid; 39 } 40 public String getEmpname() { 41 return empname; 42 } 43 public void setEmpname(String empname) { 44 this.empname = empname; 45 } 46 47 }
Proemp
1 package entity; 2 /* 3 * 表示員工和項目相關聯的表 4 * */ 5 public class Proemp { 6 private Integer rproid;//項目編號 7 private Integer rempid;//員工編號 8 9 10 public Proemp(Integer rproid, Integer rempid) { 11 this.rproid = rproid; 12 this.rempid = rempid; 13 } 14 public Proemp() { 15 } 16 public Integer getRproid() { 17 return rproid; 18 } 19 public void setRproid(Integer rproid) { 20 this.rproid = rproid; 21 } 22 public Integer getRempid() { 23 return rempid; 24 } 25 public void setRempid(Integer rempid) { 26 this.rempid = rempid; 27 } 28 29 }
Project
1 package entity; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /* 7 * 項目表 8 * */ 9 public class Project { 10 private Integer proid;//項目編號 11 private String proname;//項目名稱 12 //聲明員工集合 13 private Set<Employee> emps=new HashSet<Employee>(); 14 15 16 public Set<Employee> getEmps() { 17 return emps; 18 } 19 public void setEmps(Set<Employee> emps) { 20 this.emps = emps; 21 } 22 23 24 public Project(String proname) { 25 this.proname = proname; 26 } 27 public Integer getProid() { 28 return proid; 29 } 30 public void setProid(Integer proid) { 31 this.proid = proid; 32 } 33 public String getProname() { 34 return proname; 35 } 36 public void setProname(String proname) { 37 this.proname = proname; 38 } 39 public Project(Integer proid, String proname) { 40 this.proid = proid; 41 this.proname = proname; 42 } 43 public Project() { 44 } 45 }
這樣我們的實體類就全部創建完畢,接下來我們就可以配置映射關系文件了,既然是雙向的多對多的關系,那么肯定少不了<set></set>標簽
Project.hbm.xml
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping package="entity"> 7 <class name="Project" table="project"> 8 <id name="proid" column="proid"> 9 <generator class="increment" /> 10 </id> 11 <property name="proname" type="string" column="proname" /> 12 <!-- 配置多對多的關聯關系 設置級聯屬性--> 13 <set name="emps" table="proemp" cascade="all"> 14 <key column="rproid"></key> 15 <many-to-many class="entity.Employee" column="rempid"></many-to-many> 16 </set> 17 </class> 18 </hibernate-mapping>
Employee.hbm.xml
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping package="entity"> 7 <class name="Employee" table="Employee"> 8 <id name="empid" column="empid"> 9 <generator class="increment" /> 10 </id> 11 <property name="empname" type="string" column="empname" /> 12 <!-- 配置多對多的關聯配置 設置反轉屬性,讓項目管理關系 --> 13 <set name="pros" table="proemp" inverse="true"> 14 <key column="rempid"></key> 15 <many-to-many class="entity.Project" column="rproid"></many-to-many> 16 </set> 17 </class> 18 </hibernate-mapping>
經過以上的步驟,整個配置過程就全部完成了,當然同學們別忘記了在Hibernate配置文件(大配置)中添加對兩個映射文件(小配置)的引用
測試類
1 package test; 2 3 import org.hibernate.Session; 4 import org.hibernate.Transaction; 5 6 import util.HibernateUtil; 7 import entity.Employee; 8 import entity.Project; 9 10 public class Test { 11 public static void main(String[] args) { 12 /* 13 * 多對多的關聯關系配置 14 * 同時配置了Project和Employee之間雙向的多對多的關聯關系 15 * 關聯關系由Project方維護,並且在Project方設置了級聯屬性 16 * */ 17 //獲取Session 18 Session session=HibernateUtil.currentSession(); 19 //開啟事務 20 Transaction tx = session.beginTransaction(); 21 //構建兩個項目 22 Project pro1=new Project("項目一"); 23 Project pro2=new Project("項目二"); 24 //構建多個員工 25 Employee emp1=new Employee("巴黎的雨季"); 26 Employee emp2=new Employee("盛夏的果實"); 27 Employee emp3=new Employee("聽風"); 28 Employee emp4=new Employee("黎明前的黑暗"); 29 30 //將員工123加入項目一 31 pro1.getEmps().add(emp1); 32 pro1.getEmps().add(emp2); 33 pro1.getEmps().add(emp3); 34 //將員工234加入項目二 35 pro2.getEmps().add(emp2); 36 pro2.getEmps().add(emp3); 37 pro2.getEmps().add(emp4); 38 39 //保存項目一和項目二 40 session.save(pro1); 41 session.save(pro2); 42 //提交事務 43 tx.commit(); 44 //關閉連接 45 HibernateUtil.closeSession(); 46 } 47 }
以上代碼,我們可以發現我們僅僅保存了項目,並沒有手動的添加保存員工的代碼,也沒有手動添加保存員工和項目之間關系的表的代碼
我們可以看到Hibernate幫我們生成的sql
Hibernate很智能的通過配置文件幫我們生成了我們需要的sql,這就是面向對象思想的體現,我們自始至終都只關注了項目這個對象就完成了我們所需要的操作
我們可以看看數據庫中的記錄