溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Hibernate關聯關系怎么實現

發布時間:2021-12-06 09:37:45 來源:億速云 閱讀:170 作者:iii 欄目:編程語言

這篇文章主要介紹“Hibernate關聯關系怎么實現”,在日常操作中,相信很多人在Hibernate關聯關系怎么實現問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Hibernate關聯關系怎么實現”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

一, 一對多的單向關聯關系

[@more@]

首先先建立CustomerOrder類,代碼如下:

Customer類:

package mypack;

import java.io.Serializable;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Customer implements Serializable {

   private Long id;

   private String name;

   public Customer(String name) {

       this.name = name;

   }

   public Customer() {

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getName() {

       return this.name;

   }

   public void setName(String name) {

       this.name = name;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

Order類:

package mypack;

import java.io.Serializable;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Order implements Serializable {

   private Long id;

   private String orderNumber;

   private mypack.Customer customer;

   public Order(String orderNumber, mypack.Customer customer) {

       this.orderNumber = orderNumber;

       this.customer = customer;

   }

   public Order() {

   }

   public Order(mypack.Customer customer) {

       this.customer = customer;

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getOrderNumber() {

       return this.orderNumber;

   }

   public void setOrderNumber(String orderNumber) {

       this.orderNumber = orderNumber;

   }

   public mypack.Customer getCustomer() {

       return this.customer;

   }

   public void setCustomer(mypack.Customer customer) {

       this.customer = customer;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

CustomerOrder類的配置文件分別是Customer.hbm.xmlOrder.hbm.xml

Customer.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

 <class name="mypack.Customer" table="CUSTOMERS" >

   <id name="id" type="long" column="ID">

     <generator class="increment"/>

   id>

   <property name="name" type="string" >

       <column name="NAME" length="15" />

   property>

     

 class>

</hibernate-mapping>

Order.hbm.xml如下:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

  <class name="mypack.Order" table="ORDERS">

   

     <id name="id" type="long" column="ID">

       <generator class="increment"/>

     id>

 

     <property name="orderNumber" type="string" >

       <column name="ORDER_NUMBER" length="15" />

     property>

    <many-to-one

       name="customer"

       column="CUSTOMER_ID"

       class="mypack.Customer"

       not-null="true"

    />

   class>

hibernate-mapping>

Order.hbm.xml<many-to-one>元素建立了CustomerORDERS表的外鍵CUSTOMER_ID之間

的映射。

它包括如下屬性。

 name:設定待映射的持久化類的屬性名,此處為Order類的customer屬性。

column:設定和持久化類的屬性對應的表的外鍵,此處為ORDERS表的外鍵CUSTOMER_ID。

 class:設定持久化類的屬性的類型,此處設定customer屬性為Customer類。

 notnull:如果為ture,表示customer屬性不能為null,默認為false。

接下來我們持久化一個Customer對象以及和他關聯的Order對象:

(以下代碼并非是完整代碼,只是簡單把邏輯列出)

     

      Configuration config = new Configuration();

                        config.addClass(Customer.class)

            .       addClass(Order.class);

      sessionFactory = config.buildSessionFactory();

      Session session = sessionFactory.openSession();

      Transaction tx = null;

      tx = session.beginTransaction();

      Customer customer=new Customer("Jack");

      session.save(customer);

      Order order1=new Order("Jack_Order001",customer);

      Order order2=new Order("Jack_Order002",customer);

      session.save(order1);

      session.save(order2);

      tx.commit();

當我們要持久化一個Customer對象以及和他關聯的Order對象的時候一定要先建立Customer對象并持久化它,否則當創建Order持久對象的時候會拋出異常,如果把session.save(customer)

注銷將會在session.save(order1)拋出PropertyValueException異常。分析產生異常原因:在調用session.save(order1)方法之前,order1customer對象都是臨時對象,臨時對象就是剛剛用new創建出來,但是還沒有持久會的對象,而Hibernate不會自動持久化order1關聯的customer對象,在數據庫中意味著僅僅向ORDERS表中插入了一條記錄,并且該記錄的CUSTOMER_ID字段為null,違反了數據庫完整性約束,因為不允許ORDERS表的CUSTOMER_ID字段為null。

從上面的例子可以看出當Hibernate持久化一個臨時對象時,在默認情況下,它不會自動持久化所關聯的其他臨時對象,所以會拋出PropertyValueException異常。如果希望當Hibernate持久化Order對象時自動持久化所關聯的Customer對象,可以把<many-to-one>cascade屬性設為“saveupdate”,cascade屬性默認為“none”

                   

           <many-to-one

         name="customer"    

          column="CUSTOMER_ID"

         class="mypack.Customer"

         cascade“saveupdate”

          not-null="true"

               />

這樣就能夠在Hibernate持久化Order對象時自動持久化所關聯的Customer對象了。

二, 一對多的雙向關聯關系

我們依然使用前面的CustomerOrder的例子,由于是雙向關聯,Order類代碼如上面一樣,由于Customer類中有Order的關聯對象,因此Customer類改為如下:

package mypack;

import java.io.Serializable;

import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;

public class Customer implements Serializable {

   private Long id;

   private String name;

   private Set orders;

   public Customer(String name, Set orders) {

       this.name = name;

       this.orders = orders;

   }

   public Customer() {

  }

   public Customer(Set orders) {

       this.orders = orders;

   }

   public Long getId() {

       return this.id;

   }

   public void setId(Long id) {

       this.id = id;

   }

   public String getName() {

       return this.name;

   }

   public void setName(String name) {

       this.name = name;

   }

   public Set getOrders() {

       return this.orders;

   }

   public void setOrders(Set orders) {

       this.orders = orders;

   }

   public String toString() {

       return new ToStringBuilder(this)

           .append("id", getId())

           .toString();

   }

}

如何在映射文件中映射集合類型的order屬性呢?由于在CUSTOMERS表中沒有直接與order屬性對應的字段,因此不能用<property>元素來映射order屬性,而是要使用<set>元素:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping

PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping >

 <class name="mypack.Customer" table="CUSTOMERS" >

   <id name="id" type="long" column="ID">

     <generator class="increment"/>

   </id>

   <property name="name" type="string" >

       <column name="NAME" length="15" />

   </property>

   <set

       name="orders"

       cascade="save-update"

     

       >

       

       <key column="CUSTOMER_ID" />

       <one-to-many class="mypack.Order" />

    </set>  

 </class>

</hibernate-mapping>

<set>元素還包含兩個子元素:<key><one-to-many>,<one-to-many>元素設定所關聯的持久化類,此處為Order類,<key>元素設定與所關聯的持久化對應的表的外鍵,此處為ORDERS表的CUSTOMERS_ID字段。

它包括如下屬性:

●  <set>元素表明Customer類的orders屬性為java.util.Set集合類型。

●  <one-to-many>表明orders集合中存放的是一組Order對象。

●  <key>屬性表明ORDERS表通過外鍵CUSTOMERS_ID參照CUSTOMERS表。

●  cascade 屬性取值為"save-update",表明當保存或更新Customer對象時,會級聯保存或更新orders集合中的所有Order對象。  

接下來我們持久化一個Customer對象以及和他關聯的Order對象:

             Session session = sessionFactory.openSession();

         Transaction tx = null;

          tx = session.beginTransaction();

           Customer customer=new Customer("Tom",new HashSet());

         Order order=new Order();

         order.setOrderNumber("Tom_Order001");

           order.setCustomer(customer);

         customer.getOrders().add(order);

           session.save(customer);

         tx.commit();

<set>元素的cascade屬性為"save-update"時,Hibernate在持久化Customer對象時,會自動持久化關聯的Order對象。

如果是加載持久化對象,然后再建立關聯關系,那又該怎么做呢?如下所示:

Session session = sessionFactory.openSession();

Transaction tx = null;

tx = session.beginTransaction();

Customer customer=(Customer)session.load(Customer.class,new Long(2));

Order order=(Order)session.load(Order.class,new Long(2));

order.setCustomer(customer);

customer.getOrders().add(order);

tx.commit();

Hibernate會自動清理緩存中的所有持久化對象,按照持久化對象狀態改變來同步更新數據庫,Hibernate在清理以上Customer對象和Order對象時執行了以下兩條SQL語句:

    update ORDERS set ORDER_NUMBER='Jack_Order001',CUSTOMER_ID=2 where ID=2;

      update ORDERS set CUSTOMER_ID=2 where ID=2;

盡管只是修改了ORDERS表的一條記錄,但是以上SQL語句表明Hibernate執行了兩次update操作這是因為HIbernate根據內存中持久化對象的狀態變化來決定需要執行的SQL語句,order.setCustomer(customer)執行的相應SQL語句為:

update ORDERS set ORDER_NUMBER='Jack_Order001',CUSTOMER_ID=2 where ID=2;

customer.getOrders().add(order)執行的相應SQL語句為:

update ORDERS set CUSTOMER_ID=2 where ID=2;

重復執行對于的SQL語句會影響應用程序的性能,那么解決的辦法是把<set>元素的inverse屬性設置為true,默認為false

<set

       name="orders"

       cascade="save-update"

         inverse"ture"

       >

       

       <key column="CUSTOMER_ID" />

       <one-to-many class="mypack.Order" />

    set>

因此在映射一對多雙向關聯關系時,應該在"one"方把inverse屬性設為“ture”,這樣可以提高性能。

三,一對多雙向自身關聯關系

以食品為例,它代表商品類別,存在一對多雙向自身關聯關系。如下圖所示,水果類別屬于食品類別,同時它又包含兩個子類別:蘋果類別和桔子類別。

圖中每一種商品代表一個Category對象,這些對象形成了樹型數據結構。每個Category<span style="FONT-FAMILY:

到此,關于“Hibernate關聯關系怎么實現”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女