Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)

這篇文章主要介紹“Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

創(chuàng)新互聯(lián)建站堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:成都做網(wǎng)站、網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的豐縣網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

一,一對(duì)多的單向關(guān)聯(lián)關(guān)系

[@more@]

首先先建立Customer和Order類,代碼如下:

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();

   }

}

Customer和Order類的配置文件分別是Customer.hbm.xml和Order.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>元素建立了Customer和ORDERS表的外鍵CUSTOMER_ID之間

的映射。

它包括如下屬性。

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

●column:設(shè)定和持久化類的屬性對(duì)應(yīng)的表的外鍵,此處為ORDERS表的外鍵CUSTOMER_ID。

●  class:設(shè)定持久化類的屬性的類型,此處設(shè)定customer屬性為Customer類。

●  not-null:如果為ture,表示customer屬性不能為null,默認(rèn)為false。

接下來我們持久化一個(gè)Customer對(duì)象以及和他關(guān)聯(lián)的Order對(duì)象:

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

     

      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();

當(dāng)我們要持久化一個(gè)Customer對(duì)象以及和他關(guān)聯(lián)的Order對(duì)象的時(shí)候一定要先建立Customer對(duì)象并持久化它,否則當(dāng)創(chuàng)建Order持久對(duì)象的時(shí)候會(huì)拋出異常,如果把session.save(customer)

注銷將會(huì)在session.save(order1)拋出PropertyValueException異常。分析產(chǎn)生異常原因:在調(diào)用session.save(order1)方法之前,order1和customer對(duì)象都是臨時(shí)對(duì)象,臨時(shí)對(duì)象就是剛剛用new創(chuàng)建出來,但是還沒有持久會(huì)的對(duì)象,而Hibernate不會(huì)自動(dòng)持久化order1關(guān)聯(lián)的customer對(duì)象,在數(shù)據(jù)庫中意味著僅僅向ORDERS表中插入了一條記錄,并且該記錄的CUSTOMER_ID字段為null,違反了數(shù)據(jù)庫完整性約束,因?yàn)椴辉试SORDERS表的CUSTOMER_ID字段為null。

從上面的例子可以看出當(dāng)Hibernate持久化一個(gè)臨時(shí)對(duì)象時(shí),在默認(rèn)情況下,它不會(huì)自動(dòng)持久化所關(guān)聯(lián)的其他臨時(shí)對(duì)象,所以會(huì)拋出PropertyValueException異常。如果希望當(dāng)Hibernate持久化Order對(duì)象時(shí)自動(dòng)持久化所關(guān)聯(lián)的Customer對(duì)象,可以把<many-to-one>的cascade屬性設(shè)為“save-update”,cascade屬性默認(rèn)為“none”:

                   

           <many-to-one

         name="customer"    

          column="CUSTOMER_ID"

         class="mypack.Customer"

         cascade=“save-update”

          not-null="true"

               />

這樣就能夠在Hibernate持久化Order對(duì)象時(shí)自動(dòng)持久化所關(guān)聯(lián)的Customer對(duì)象了。

二,一對(duì)多的雙向關(guān)聯(lián)關(guān)系

我們依然使用前面的Customer和Order的例子,由于是雙向關(guān)聯(lián),Order類代碼如上面一樣,由于Customer類中有Order的關(guān)聯(lián)對(duì)象,因此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屬性對(duì)應(yīng)的字段,因此不能用<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>元素還包含兩個(gè)子元素:<key>和<one-to-many>,<one-to-many>元素設(shè)定所關(guān)聯(lián)的持久化類,此處為Order類,<key>元素設(shè)定與所關(guān)聯(lián)的持久化對(duì)應(yīng)的表的外鍵,此處為ORDERS表的CUSTOMERS_ID字段。

它包括如下屬性:

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

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

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

●  cascade屬性取值為"save-update",表明當(dāng)保存或更新Customer對(duì)象時(shí),會(huì)級(jí)聯(lián)保存或更新orders集合中的所有Order對(duì)象。  

接下來我們持久化一個(gè)Customer對(duì)象以及和他關(guān)聯(lián)的Order對(duì)象:

            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();

當(dāng)<set>元素的cascade屬性為"save-update"時(shí),Hibernate在持久化Customer對(duì)象時(shí),會(huì)自動(dòng)持久化關(guān)聯(lián)的Order對(duì)象。

如果是加載持久化對(duì)象,然后再建立關(guān)聯(lián)關(guān)系,那又該怎么做呢?如下所示:

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會(huì)自動(dòng)清理緩存中的所有持久化對(duì)象,按照持久化對(duì)象狀態(tài)改變來同步更新數(shù)據(jù)庫,Hibernate在清理以上Customer對(duì)象和Order對(duì)象時(shí)執(zhí)行了以下兩條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執(zhí)行了兩次update操作這是因?yàn)镠Ibernate根據(jù)內(nèi)存中持久化對(duì)象的狀態(tài)變化來決定需要執(zhí)行的SQL語句,order.setCustomer(customer)執(zhí)行的相應(yīng)SQL語句為:

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

customer.getOrders().add(order)執(zhí)行的相應(yīng)SQL語句為:

update ORDERS set CUSTOMER_ID=2 where ID=2;

重復(fù)執(zhí)行對(duì)于的SQL語句會(huì)影響應(yīng)用程序的性能,那么解決的辦法是把<set>元素的inverse屬性設(shè)置為true,默認(rèn)為false:

<set

       name="orders"

       cascade="save-update"

         inverse="ture"

       >

       

       <key column="CUSTOMER_ID" />

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

    set>

因此在映射一對(duì)多雙向關(guān)聯(lián)關(guān)系時(shí),應(yīng)該在"one"方把inverse屬性設(shè)為“ture”,這樣可以提高性能。

三,一對(duì)多雙向自身關(guān)聯(lián)關(guān)系

以食品為例,它代表商品類別,存在一對(duì)多雙向自身關(guān)聯(lián)關(guān)系。如下圖所示,水果類別屬于食品類別,同時(shí)它又包含兩個(gè)子類別:蘋果類別和桔子類別。

圖中每一種商品代表一個(gè)Category對(duì)象,這些對(duì)象形成了樹型數(shù)據(jù)結(jié)構(gòu)。每個(gè)Category<span style="FONT-FAMILY:

到此,關(guān)于“Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

當(dāng)前文章:Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)
文章路徑:http://bm7419.com/article24/pcgije.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供移動(dòng)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作外貿(mào)建站、全網(wǎng)營(yíng)銷推廣、外貿(mào)網(wǎng)站建設(shè)軟件開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)