程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> Hibernate總結(二),hibernate總結

Hibernate總結(二),hibernate總結

編輯:JAVA綜合教程

Hibernate總結(二),hibernate總結


在上一篇Hibernate總結(一)簡單總結了一級緩存,快照,增刪改查的簡單使用,這一篇總結兩張表的級聯操作。

級聯涉及到三種情況,many-many,1-many,many-1。

  • 首先是1-many,many-1情況,所以先設置一個情景:客戶與訂單的關系
//因為太占版面緣故,沒有列出get()/set()方法
public class Customer {
    private Integer id;
    private String name;
    private Set<Order> orders = new HashSet<Order>();//1對多
}
public class Order {
    private Integer id;
    private String name;
    private Customer customer;//多對1
}

接下來是hibernate.cfg.xml與兩個實體類的配置文件Order.hbm.xml與Customer.hbm.xml,第一個不多說,主要是映射文件的配置

//Customer.hbm.xml
<hibernate-mapping package="king.domain">
    <class name="Customer" table="t_customer">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name"></property>
        <!-- 一對多關系 -->
        <!-- 
       inverse:true 不維護關系,交給擁有外鍵一方維護
       cascade:save-update(級聯保存與級聯更新),當然還有其它選項,delete(級聯刪除),all(級聯保存,更新,刪除),none(默認沒有級聯)
   --> <set name="orders" inverse="true" cascade="save-update"> <key column="cid"></key> <!-- 在Order表中的外鍵的名字--> <one-to-many class="Order"/> </set> </class> </hibernate-mapping> //Order.hbm.xml <hibernate-mapping package="king.domain"> <class name="Order" table="t_order"> <id name="id" column="id"> <generator class="native"></generator> </id> <property name="name" column="name"></property> <!-- 多對一關系 --> <!-- 含有外鍵一方維護關系 --> <many-to-one name="customer" column="cid" class="Customer"></many-to-one> </class> </hibernate-mapping>

一切准備就緒,開始級聯的代碼:

因為代碼中大量使用了得到連接,關閉連接操作,所以我使用了模板設計模式,在我的文章《Hibernate-模板模式》有講解

    /**
     * 級聯保存:
     * 1.inverse="true",維護關系,最好只有一方維護,而且是擁有外鍵一方維護
     * 2.cascade="save-update",級聯保存與級聯更新
     */
    @Test
    public void test0() {
        new SessionTemplate(){
            @Override
            public void fun(Session s) {
                Customer c=new Customer();
                c.setName("King");
                Order o1=new Order();
                o1.setName("炒面");
                Order o2=new Order();
                o2.setName("肉");
                
                o1.setCustomer(c);//由擁有外鍵一方維護關系
                o2.setCustomer(c);
                
                s.save(c);
                s.save(o1);
                s.save(o2);//這樣框架只執行了3條SQL語句
            }
        }.execute();
    }
    /**
     * 級聯刪除:
     * 1.inverse="false"為默認處理方式:把客戶的訂單的外鍵修改為null,然後再刪除客戶
     * 2.inverse="true"若客戶不處理,會出錯
     */
    @Test
    public void test1() {
        new SessionTemplate(){
            @Override
            public void fun(Session s) {
         //這是沒有使用級聯刪除的情況,這時cascade為save-update Customer c=(Customer) s.get(Customer.class, 3); for(Order o:c.getOrders()){ s.delete(o); } s.delete(c);//此時,inverse="true",所以前面刪除了所有客戶的訂單才能刪除客戶

         //更改配置文件,cascade為delete,這時就是級聯刪除
                Customer c=(Customer) s.get(Customer.class, 3);
                s.delete(c);//這時不需要手動刪除訂單了
            }
        }.execute();
    }
    /**
     * 級聯更新
   * cascade為save-update  */ @Test public void test2() { new SessionTemplate(){ @Override public void fun(Session s) { Customer c=(Customer) s.get(Customer.class, 2); for(Order o:c.getOrders()){ o.setName("羊雜湯");//持久態,不需要更新 } } }.execute(); }

查詢涉及到了加載策略,所以很復雜,所以將在寫在下一篇中。

  • 接下來說many-many的情況,還是先設置一個情景:學生與課程的關系
public class Student {
    private Integer id;
    private String name;
    private Set<Course> courses=new HashSet<>();//多對多
}
public class Course {
    private Integer id;
    private String name;
    private Set<Student> students=new HashSet<>();//多對多
}

接下來是兩個實體類與數據庫表的映射文件:

//Student.hbm.xml
<hibernate-mapping package="king.domain">
    <class name="Student" table="t_student">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name"></property>
        <!-- 多對多關系,在多對多中,需要雙方都設置存儲關系的表名 -->
        <set name="courses" cascade="save-update" table="t_selectcourse">
            <key column="sid"></key>
            <many-to-many class="Course" column="cid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>
//Course.hbm.xml
<hibernate-mapping package="king.domain">
    <class name="Course" table="t_course">
        <id name="id" column="id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="name"></property>
        <!-- 多對多關系 -->
        <!-- 維護權反轉給對方 -->
        <set name="students" inverse="true" table="t_selectcourse">
            <key column="cid"></key>
            <many-to-many class="Student" column="sid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

一切准備繼續,開始代碼工作:

    /**
     * 多對多
     * 級聯保存:
   * 本來想也寫上級聯刪除與級聯更新,但是發現寫的代碼和我想要實現的結果不同,故沒有貼出代碼,額...我的意思就是我也不會...挺尴尬... */ @Test public void test0() { new SessionTemplate(){ @Override public void fun(Session s) { Student s1=new Student(); s1.setName("King"); Course c1=new Course(); c1.setName("數學"); Course c2=new Course(); c2.setName("英語"); s1.getCourses().add(c1);//由學生維護關系 s1.getCourses().add(c2);//由學生維護關系 s.save(s1); } }.execute(); }

增刪改查,現在就差“查”沒有寫出,我將在下一篇總結中寫出Hibernate的關於查詢的加載策略。

 

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