首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Hibernate學習筆記(五):一對多單向關聯映射實戰與缺陷分析

     編輯:Java 相關知識

承接上篇「多對一單向關聯」,本文反向講解一對多單向關聯映射。二者角度不同:學生視角是多對一,班級視角是一對多,但對象關係建立方式迥異。

類圖與核心概念

Hibernate透過操作「一」端(Class),間接/自動操作「多」端(Student)。添加班級時自動級聯添加學生,查詢班級可獲取所有學生。

實體類定義

public class Class {
    private int id;
    private String name;
    private Set<Student> students;  // 集合屬性持有多端引用
    // getter/setter...
}

public class Student {
    private int id;
    private String name;
    // getter/setter...  // 學生端無班級引用(單向)
}

映射配置:one-to-many元素

<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"/>
        </set>
    </class>
</hibernate-mapping>

one-to-many自動在t_student建立外鍵classid映射t_class.id。

測試代碼與執行結果

public class One2ManyTest extends TestCase {
    public void testSave2() {
        Session session = HibernateUtils.getSession();
        session.beginTransaction();

        Student student1 = new Student(); student1.setName("張三");
        Student student2 = new Student(); student2.setName("李四");
        // 必須先save轉為Persistent狀態,否則拋TransientObjectException
        session.save(student1); session.save(student2);

        Class classes = new Class(); classes.setName("提高班");
        Set<Student> students = new HashSet<>();
        students.add(student1); students.add(student2);
        classes.setStudents(students);

        session.save(classes);  // 可成功保存
        session.getTransaction().commit();
    }
}

執行前後數據對比:

一對多vs多對一:映射原理一致,維護關係不同

關聯類型維護關係加載行為缺陷
多對一多指向一加載多時自動加載一—
一對多一指向多加載一時自動加載多見下文

一對多單向維護的兩大缺陷

  1. 外鍵非空約束衝突:Student端不知Class存在(無反向引用),保存Student時classid=null。若資料庫設NOT NULL將無法保存。
  2. 多餘UPDATE語句:Class維護關係,保存時先插入classid=NULL,再UPDATE設置外鍵。產生額外SQL開銷。

解決方案:改用雙向關聯(下篇講解),由「多」端維護關係,inverse="true"關閉「一」端維護。

參考:一口一口吃掉Hibernate(五)

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved