~~~接着之前的Hibernate框架接着學習(上篇面試過后發現真的需要學習一下框架了,不然又被忽悠讓去培訓。)~~~
1:Hibernate的關聯映射,存在一對多和多對一映射,多對多映射:
1.1:一對多和多對一映射,舉例說明:
學生和老師:
一個老師可以教多個學生 【一對多映射】
多個學生可以被一個老師教【多對一映射】
部門與員工:
一個部門有多個員工【一對多映射】
多個員工屬於一個部門【多對一映射】
1.2:多對多,舉例說明:
項目和開發員工:【雙向一對多即多對多映射】
一個項目有多個開發人員【一對多】
一個開發人員參與多個項目【一對多】
2:一對多和多對一映射,理清以下思路就可以進行簡單的開發了:
2.1:首先導入hibernate框架所需要的包哦~~~
2.2:由於是在hibernate.cfg.xml配置里面自動生成數據庫和表,所以不用手動創建了
2.3:進入正題,開發創建實體類;下面是兩個實體類的關鍵點;
Dept.java:
注意private Set<Employee> emps;//部門對應多個員工,即一對多的關系
Employee.java:
private Dept dept;//員工和部門的關系

1 package com.bie.po; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /** 7 * @author BieHongLi 8 * @version 創建時間:2017年3月20日 上午9:45:21 9 * 部門的實體類 10 * 關鍵點,是通過部門實體類維護到員工的實體類 11 */ 12 public class Dept { 13 14 private int deptId;//部門編號 15 private String deptName;//部門名稱 16 17 private Set<Employee> emps;//部門對應多個員工,即一對多的關系 18 //private Set<Employee> emps = new HashSet<>();//方便賦值,這里可以直接創建實例化 19 20 21 public int getDeptId() { 22 return deptId; 23 } 24 public void setDeptId(int deptId) { 25 this.deptId = deptId; 26 } 27 public String getDeptName() { 28 return deptName; 29 } 30 public void setDeptName(String deptName) { 31 this.deptName = deptName; 32 } 33 public Set<Employee> getEmps() { 34 return emps; 35 } 36 public void setEmps(Set<Employee> emps) { 37 this.emps = emps; 38 } 39 40 41 }

1 package com.bie.po; 2 /** 3 * @author BieHongLi 4 * @version 創建時間:2017年3月20日 上午9:46:45 5 * 員工的實體類 6 */ 7 public class Employee { 8 9 private int empId;//員工的編號 10 private String empName;//員工的名稱 11 private double salary;//員工的薪資 12 13 private Dept dept;//員工和部門的關系 14 15 public int getEmpId() { 16 return empId; 17 } 18 public void setEmpId(int empId) { 19 this.empId = empId; 20 } 21 public String getEmpName() { 22 return empName; 23 } 24 public void setEmpName(String empName) { 25 this.empName = empName; 26 } 27 public double getSalary() { 28 return salary; 29 } 30 public void setSalary(double salary) { 31 this.salary = salary; 32 } 33 public Dept getDept() { 34 return dept; 35 } 36 public void setDept(Dept dept) { 37 this.dept = dept; 38 } 39 40 41 }
2.4:創建好實體類就可以進行創建hibernate的映射文件了,如Dept.hbm.xml和Employee.hbm.xml映射文件;
部門表進行映射的時候:
需要注意使用set集合進行映射的注意點:
Dept映射關鍵點: 1:指定映射的集合屬性:"emps" 2:集合屬性對應的集合表:"20171021_employee" 3:集合表的外鍵字段"20171021_employee.deptId" 4:集合元素的類型
員工表進行映射的時候:
需要注意<many-to-one name="dept" column="deptId" class="Dept"></many-to-one>
將一個對象映射成為外鍵字段,只能使用many-to-one這個配置。
Employee映射關鍵點: 1:映射的部門屬性:dept 2:映射的部門對象,對應的外鍵字段:dept_id 3:指定部門的類型
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屬性直接初始化了,下面就可以直接引用了 --> 7 <hibernate-mapping package="com.bie.po"> 8 <class name="Dept" table="dept"> 9 <!-- 第一首先寫主鍵映射 --> 10 <id name="deptId" column="deptId"> 11 <generator class="native"></generator> 12 </id> 13 <!-- 第二寫非主鍵映射 --> 14 <property name="deptName" column="deptName" length="20" type="string"></property> 15 16 <!-- 17 第三寫其他映射,比如這里的set集合映射, 18 --> 19 <!-- 20 一對多關聯映射配置(通過部門管理到員工) 21 Dept映射關鍵點 22 (1)指定映射的集合屬性:""emps; 23 (2)集合屬性對應的集合表:"employee"; 24 (3)集合表的外鍵字段:employee.empId 25 (4)集合元素的類型 26 --> 27 <!-- name指定了映射的集合的屬性,即集合實例化的emps;table指定了集合屬性對應的集合表 --> 28 <set name="emps" table="employee"> 29 <!--column指定了集合表的外鍵 --> 30 <key column="deptId"></key> 31 <!-- class由於上面已經寫了包名,這里直接使用即可 --> 32 <one-to-many class="Employee"/> 33 </set> 34 </class> 35 </hibernate-mapping> 36 37 38
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 <!-- 這里指定package,里面就可以直接引用了 --> 6 <hibernate-mapping package="com.bie.po"> 7 <class name="Employee" table="employee"> 8 <!-- 1:主鍵映射 --> 9 <id name="empId" column="empId"> 10 <generator class="native"></generator> 11 </id> 12 13 <!-- 2:非主鍵映射 --> 14 <property name="empName" column="empName" length="20" type="string"></property> 15 <property name="salary" column="salary" type="double"></property> 16 17 <!-- 18 多對一的映射配置;Employee映射的關鍵點 19 (1)映射的部門屬性:dept 20 (2)映射的部門對新,對應的外鍵字段:deptId 21 (3)部門的類型:Dept 22 --> 23 <many-to-one name="dept" column="deptId" class="Dept"></many-to-one> 24 </class> 25 26 </hibernate-mapping> 27 28
2.5:配置好映射文件,就可以配置hibernate的配置文件了,hibernate.cfg.xml;
注意:
第二部分其他配置的時候注意顯示sql語句和方言還有自動創建數據表這些細節問題
第三部分加載映射文件的寫法也需要注意
1 <!DOCTYPE hibernate-configuration PUBLIC 2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 3 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 4 5 <hibernate-configuration> 6 <session-factory> 7 <!-- 第一部分:連接數據庫的操作,加載驅動,連接數據庫的url和賬號密碼 --> 8 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 9 <property name="hibernate.connection.url">jdbc:mysql:///test</property> 10 <property name="hibernate.connection.username">root</property> 11 <property name="hibernate.connection.password">123456</property> 12 13 <!-- 第二部分:其他相關配置 --> 14 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 15 <property name="hibernate.show_sql">true</property> 16 <property name="hibernate.format_sql">true</property> 17 <property name="hibernate.hbm2ddl.auto">update</property> 18 <!-- <property name="hibernate.hbm2ddl.auto">create</property> --> 19 20 <!-- 第三部分:加載映射文件 --> 21 <mapping resource="com/bie/po/Dept.hbm.xml"/> 22 <mapping resource="com/bie/po/Employee.hbm.xml"/> 23 </session-factory> 24 </hibernate-configuration>
2.6:最后就可以使用junit進行測試了,如下所示:
(1)首先清楚下面兩種測試的區別是是否在實體類實例化set集合
private Set<Employee> emps;//部門對應多個員工,即一對多的關系
private Set<Employee> emps = new HashSet<>();//方便賦值,這里可以直接創建實例化
(2)下面兩種情況都可以設置好部門和員工的信息。就是在配置映射的時候一定搞清楚set集合映射的配置和many-to-one的配置
I:從部門的一方設置員工的信息【不推薦】
dept.getEmps().add(emp1);
dept.getEmps().add(emp2);
II:從員工的一方設置好部門的信息【推薦,在一對多和多對一的關聯關系中,保存數據最好是通過多對一來維護關系,這樣可以減少update語句的生成,從而提高hibernate的利用效率】
emp1.setDept(dept);
emp2.setDept(dept);
(3)最后是保存的順序,保存的順序最好是先保存一的一方再保存多的一方,這樣可以提高效率,少執行sql語句
第一種方法(推薦)
session.save(dept);//先保存一的一方
session.save(emp1);
session.save(emp2);//再保存多的一方,關系會自動維護(但是映射配置必須配置好的 )
第二種方法(不推薦)
session.save(emp1);//先保存多的一方,關系會自動維護(但是映射配置必須配置好的 )
session.save(emp2);
session.save(dept);//再保存一的一方
1 package com.bie.test; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import org.hibernate.Session; 7 import org.hibernate.SessionFactory; 8 import org.hibernate.cfg.Configuration; 9 import org.junit.Test; 10 11 import com.bie.po.Dept; 12 import com.bie.po.Employee; 13 14 /** 15 * @author BieHongLi 16 * @version 創建時間:2017年3月20日 上午10:29:38 17 * 18 */ 19 public class OneManyTest { 20 21 //初始化靜態的session工廠 22 private static SessionFactory sf = null; 23 static{ 24 //這里使用簡寫的方法,首先加載默認的hibernate.cfg.xml,然后是創建session工廠 25 sf = new Configuration().configure().buildSessionFactory(); 26 } 27 28 @Test 29 public void test(){ 30 //創建session,import org.hibernate.Session; 31 Session session = sf.openSession(); 32 //session開始事務 33 session.beginTransaction(); 34 35 //1:關鍵點,部門對象的初始化,創建一個部門 36 Dept dept = new Dept(); 37 dept.setDeptName("開發部"); 38 39 //2:關鍵點,員工的初始化,創建兩個人對象 40 Employee emp1 = new Employee(); 41 emp1.setEmpName("張三"); 42 Employee emp2 = new Employee(); 43 emp2.setEmpName("李四"); 44 45 //3:然后將創建的人添加到set集合中 46 Set<Employee> set = new HashSet<>(); 47 set.add(emp1); 48 set.add(emp2); 49 50 //4:再將set集合中保存的人保存到部門里面 51 dept.setEmps(set); 52 53 //5:最后保存員工對象,部門 54 session.save(emp1); 55 session.save(emp2); 56 session.save(dept); 57 58 //提交事務,省去了事務new實例化了 59 session.getTransaction().commit(); 60 //關閉session 61 session.close(); 62 } 63 64 @Test 65 public void test2(){ 66 //創建session,import org.hibernate.Session; 67 Session session = sf.openSession(); 68 //session開始事務 69 session.beginTransaction(); 70 71 //1:關鍵點,部門對象的初始化,創建一個部門 72 Dept dept = new Dept(); 73 dept.setDeptName("研發部2"); 74 75 //2:關鍵點,員工的初始化,創建兩個人對象 76 Employee emp1 = new Employee(); 77 emp1.setEmpName("小三子2"); 78 Employee emp2 = new Employee(); 79 emp2.setEmpName("小四子2"); 80 81 //3:再將set集合中保存的人保存到部門里面 82 //dept.getEmps().add(emp1); 83 //dept.getEmps().add(emp2); 84 85 //或者是從員工的一方設置好部門的信息 86 emp1.setDept(dept); 87 emp2.setDept(dept); 88 89 //4:最后保存員工對象,部門,保存的順序也會影響sql語句的,所以最好先保存一的一方 90 session.save(dept);//先保存一的一方 91 session.save(emp1); 92 session.save(emp2);//再保存多的一方,關系會自動維護(但是映射配置必須配置好的 ) 93 94 //提交事務,省去了事務new實例化了 95 session.getTransaction().commit(); 96 //關閉session 97 session.close(); 98 } 99 100 }
測試結果如下所示(由於set集合在實體類里面初始化和不初始化出現下面兩種情況,所以需要注意兩種測試測試的方法):
3:多對多映射,這個需要理解清楚他們之間的關系。不然很容易搞混亂的。
3.1:創建實體類:
Project.java
項目下面的多個員工
private Set<Develope> deve = new HashSet<Develope>();
Develope.java
開發人員參入的多個項目
private Set<Project> project = new HashSet<Project>();

1 package com.bie.domain; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /** 7 * @author BieHongLi 8 * @version 創建時間:2017年3月20日 下午5:32:42 9 * 項目的實體類 10 */ 11 public class Project { 12 13 private int proId; 14 private String proName; 15 16 //項目下面的多個員工 17 private Set<Develope> deve = new HashSet<Develope>(); 18 19 public int getProId() { 20 return proId; 21 } 22 public void setProId(int proId) { 23 this.proId = proId; 24 } 25 public String getProName() { 26 return proName; 27 } 28 public void setProName(String proName) { 29 this.proName = proName; 30 } 31 public Set<Develope> getDeve() { 32 return deve; 33 } 34 public void setDeve(Set<Develope> deve) { 35 this.deve = deve; 36 } 37 38 }

1 package com.bie.domain; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 /** 7 * @author BieHongLi 8 * @version 創建時間:2017年3月20日 下午5:33:53 9 * 項目參入人員 10 */ 11 public class Develope { 12 13 private int deveId; 14 private String deveName; 15 16 //開發人員參入的多個項目 17 private Set<Project> project = new HashSet<Project>(); 18 19 public int getDeveId() { 20 return deveId; 21 } 22 public void setDeveId(int deveId) { 23 this.deveId = deveId; 24 } 25 public String getDeveName() { 26 return deveName; 27 } 28 public void setDeveName(String deveName) { 29 this.deveName = deveName; 30 } 31 public Set<Project> getProject() { 32 return project; 33 } 34 public void setProject(Set<Project> project) { 35 this.project = project; 36 } 37 38 39 }
3.2:如上面的,創建好實體類就可以配置就可以配置映射文件了:【注意,主鍵一定設置自增,開始我沒寫,報錯了哦~~~】
Project.hbm.xml:【關鍵點】
<!-- 實體類set集合實例化的對象name和中間表table -->
<set name="deve" table="relation">
<!-- 設置項目的主鍵 -->
<key column="proId"></key>
<!-- 設置人員的主鍵作為中間表的外鍵和人員對應的實體類 -->
<many-to-many column="deve_Id" class="Develope"></many-to-many>
</set>
Develope.hbm.xml:【關鍵點】
<set name="project" table="relation">
<key column="deveId"></key>
<many-to-many column="proId" class="Project"></many-to-many>
</set>
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="com.bie.domain"> 7 <class name="Project" table="project"> 8 <!-- 主鍵映射 --> 9 <id name="proId" column="proId"> 10 <generator class="native"></generator> 11 </id> 12 <!-- 非主鍵映射 --> 13 <property name="proName" column="proName" type="string" length="20"></property> 14 15 <!-- 其他映射配置 --> 16 <!-- 17 多對多映射: 18 1:映射的集合屬性:deve 19 2:集合屬性,對應的中間表:relation 20 3:外鍵字段:proId 21 4:外鍵字段,對應的中間表字段:deveId 22 5:集合屬性元素的類型 23 24 --> 25 <!-- 實體類set集合實例化的對象name和中間表table --> 26 <set name="deve" table="relation"> 27 <!-- 設置項目的主鍵 --> 28 <key column="proId"></key> 29 <!-- 設置人員的主鍵作為中間表的外鍵和人員對應的實體類 --> 30 <many-to-many column="deve_Id" class="Develope"></many-to-many> 31 </set> 32 33 </class> 34 35 </hibernate-mapping> 36 37
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 <hibernate-mapping package="com.bie.domain"> 6 <class name="Develope" table="develope"> 7 <!-- 主鍵映射 --> 8 <id name="deveId" column="deveId"> 9 <generator class="native"></generator> 10 </id> 11 <!-- 非主鍵映射 --> 12 <property name="deveName" column="deveName"></property> 13 14 <!-- 其他映射配置 --> 15 <!-- 16 多對多映射:員工方 17 1:映射的集合屬性:project 18 2:集合屬性,對應的中間表:relation 19 3:外鍵字段:deveId 20 4:外鍵字段,對應的中間表字段:proId 21 5:集合屬性元素的類型 22 --> 23 <set name="project" table="relation"> 24 <key column="deveId"></key> 25 <many-to-many column="proId" class="Project"></many-to-many> 26 </set> 27 28 </class> 29 30 </hibernate-mapping> 31 32
3.3:這里配置Hibernate.cfg.xml,和上面的配置類似。
<!-- 第三部門:多對多映射的映射加載文件 -->
<mapping resource="com/bie/domain/Project.hbm.xml"/>
<mapping resource="com/bie/domain/Develope.hbm.xml"/>

1 <!DOCTYPE hibernate-configuration PUBLIC 2 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 3 "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 4 5 <hibernate-configuration> 6 <session-factory> 7 <!-- 第一部分:連接數據庫的操作,加載驅動,連接數據庫的url和賬號密碼 --> 8 <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> 9 <property name="hibernate.connection.url">jdbc:mysql:///test</property> 10 <property name="hibernate.connection.username">root</property> 11 <property name="hibernate.connection.password">123456</property> 12 13 <!-- 第二部分:其他相關配置 --> 14 <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 15 <property name="hibernate.show_sql">true</property> 16 <!-- <property name="hibernate.format_sql">true</property> --> 17 <property name="hibernate.hbm2ddl.auto">update</property> 18 <!-- <property name="hibernate.hbm2ddl.auto">create</property> --> 19 20 <!-- 第三部分:加載映射文件 --> 21 <mapping resource="com/bie/po/Dept.hbm.xml"/> 22 <mapping resource="com/bie/po/Employee.hbm.xml"/> 23 24 25 <!-- 第三部門:多對多映射的映射加載文件 --> 26 <mapping resource="com/bie/domain/Project.hbm.xml"/> 27 <mapping resource="com/bie/domain/Develope.hbm.xml"/> 28 29 </session-factory> 30 </hibernate-configuration>
3.4:最后測試就可以了,多對多的關系映射:
1 package com.bie.test; 2 3 import org.hibernate.Session; 4 import org.hibernate.SessionFactory; 5 import org.hibernate.cfg.Configuration; 6 import org.junit.Test; 7 8 import com.bie.domain.Develope; 9 import com.bie.domain.Project; 10 11 /** 12 * @author BieHongLi 13 * @version 創建時間:2017年3月20日 下午7:27:00 14 * 多對多的測試 15 */ 16 public class Many2ManyTest { 17 18 public static SessionFactory sf =null; 19 static{ 20 sf = new Configuration().configure().buildSessionFactory(); 21 } 22 23 @Test 24 public void test(){ 25 Session session = sf.openSession(); 26 session.beginTransaction(); 27 28 //創建項目和員工進行保存測試 29 Project pro1 = new Project(); 30 pro1.setProName("企業費用管理系統"); 31 Project pro2 = new Project(); 32 pro2.setProName("企業辦公系統"); 33 34 Develope dev1 = new Develope(); 35 dev1.setDeveName("張三"); 36 Develope dev2 = new Develope(); 37 dev2.setDeveName("李四"); 38 Develope dev3 = new Develope(); 39 dev3.setDeveName("王五"); 40 41 //設置關系, 42 pro1.getDeve().add(dev1); 43 pro1.getDeve().add(dev2); 44 pro2.getDeve().add(dev1); 45 pro2.getDeve().add(dev3); 46 47 //保存到session中,保存員工和項目到session中 48 session.save(dev1); 49 session.save(dev2); 50 session.save(dev3); 51 52 session.save(pro1); 53 session.save(pro2); 54 55 //提交 56 session.getTransaction().commit(); 57 session.close(); 58 } 59 60 }
只有學習才能使我快樂~~~,加油~~~