程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Hibernate學習(五)一對多單向關聯映射

Hibernate學習(五)一對多單向關聯映射

編輯:關於JAVA

在上一篇博客《一口一口吃掉Hibernate(四)——多對一單向關聯映射》中,介紹了多對一的關聯映射,今天就反過來說一下一對多的單向關聯映射。

可能有人會對這2篇博客的題目有點混淆不清,跟日常說的關系有點不同。我們日常說的比如父子關系,夫妻關系都是說的雙向關系,而現在討論的則是單向關系,所以也就有了多對一和一對多的說法。

二者的關系其實很簡單,只是角度不同而已。比如說學生和班級的關系。如果從學生角度來看,是多對一的關系。而從班級角度來看,則是一對多的關系。說法很簡單,但是在對象和關系的建立卻是不一樣的。

先看一下一對多的類圖(貌似好多人的聚合關系都畫錯了):

Hibernate對於一對多的關系的處理,是通過操作Class端,間接操作或者自動操作Student端。比如添加,我直接添加Class端的數據,多個Student就會被添加自動添加進去。也可以通過這個Class獲取到所有對應的學生信息。跟著我來配置一下吧:

首先定義實體類【Class】【Student】

package com.bjpowernode.hibernate;  
      
import java.util.Set;  
      
/** 
 * 班級類 
 * @author Longxuan 
 * 
 */
public class Class {  
      
    private int id;  
          
    private String name;  
          
    private Set<Student> students;  
      
    public Set<Student> getStudents() {  
        return students;  
    }  
      
    public void setStudents(Set<Student> students) {  
        this.students = students;  
    }  
      
    public int getId() {  
        return id;  
    }  
      
    public void setId(int id) {  
        this.id = id;  
    }  
      
    public String getName() {  
        return name;  
    }  
      
    public void setName(String name) {  
        this.name = name;  
    }  
}  
      
      
package com.bjpowernode.hibernate;  
      
/** 
 * 學生類 
 *URL:http://www.bianceng.cn/Programming/Java/201410/45831.htm
 * @author Longxuan 
 * 
 */
public class Student {  
      
    private int id;  
          
    private String name;  
          
    public int getId() {  
        return id;  
    }  
      
    public void setId(int id) {  
        this.id = id;  
    }  
      
    public String getName() {  
        return name;  
    }  
      
    public void setName(String name) {  
        this.name = name;  
    }  
      
          
}

hibernate.cfg.xml配置文件和hibernate.properties配置文件跟上篇博文中的一致,只是數據庫名不同而已。自行修改或者不修改都可。

Hibernate提供了one-to-many來簡化一對多的映射關系。不用我們自己再去實現,只需要在映射文件中進行配置即可:

<?xml version="1.0"?>  
<!DOCTYPE hibernate-mapping PUBLIC   
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<hibernate-mapping package="com.bjpowernode.hibernate">  
    <class name="Student" table="t_student">  
        <id name="id">  
            <generator class="native" />  
        </id>  
        <property name="name" />  
    </class>  
          
    <class name="Class" table="t_class">  
        <id name="id">  
            <generator class="native" />  
        </id>  
        <property name="name" />  
        <!-- 設置Set,用於關聯多個學生 -->
        <set name="students">  
            <!-- 在t_student表中創建外鍵classid,與本表的id對應 -->
            <key column="classid"></key>  
            <one-to-many class="Student"></one-to-many>  
        </set>  
    </class>    
          
</hibernate-mapping>

配置了one-to-many會自動在t_student表中創建外鍵classid,與t_class的id映射。

測試類【One2ManyTest】:

package com.bjpowernode.hibernate;  
      
import java.util.HashSet;  
import java.util.Iterator;  
import java.util.Set;  
import junit.framework.TestCase;  
import org.hibernate.Session;  
import org.hibernate.Transaction;  
      
public class One2ManyTest extends TestCase {  
              
    public void testSave2() {  
        Session session = null;  
        try {  
            session = HibernateUtils.getSession();  
            session.beginTransaction();  
                  
            Student student1 = new Student();  
            student1.setName("張三");  
            //必須先將student1轉化為Persistent狀態,否則會拋TransientObjectException
		//URL:http://www.bianceng.cn/Programming/Java/201410/45831.htm
            session.save(student1);  
                  
            Student student2 = new Student();  
            student2.setName("李四");  
            //必須先將student1轉化為Persistent狀態,否則會拋TransientObjectException  
            session.save(student2);  
                  
            Class classes = new Class();  
            classes.setName("提高班");  
                  
            Set<Student> students = new HashSet<Student> ();  
            students.add(student1);  
            students.add(student2);  
            classes.setStudents(students);  
                  
            //可以成功保存數據。  
            //先添加數據,將關系字段設置為null,再用update語句來更新關系字段  
            //但是會發出多余的update語句來維持關系。  
            session.save(classes);  
            session.getTransaction().commit();  
               
        }catch(Exception e) {  
            e.printStackTrace();  
            session.getTransaction().rollback();  
        }finally {  
            HibernateUtils.closeSession(session);  
        }  
    }

結果圖:

執行測試前:

,執行測試後:

通過上面的例子,我們可以看出,其實一對多關聯映射和多對一關聯映射映射原理是一致的,都是在多的一端加入一個外鍵,指向一的一端。

它們的區別在於維護的關系不同:

多對一維護的關系是:多指向一的關系,有了此關系,在加載多的時候可以將一加載上來

一對多維護的關系是:一指向多的關系,有了此關系,在加載一的時候可以將多加載上來

在一的一端維護關系存在缺陷:

因為多的一端Student不知道Class的存在(也就是Student沒有維護與Class的關系)所以在保存Student的時候關系字段classid是為null的,如果將該關系字段設置為非空,則將無法保存數據

另外因為Student不維護關系,而Class維護關系,Class就會發出多余的update語句,保證Class和Student有關系,這樣加載Class的時候才可以把該Class對應的學生加載上來

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved