這篇文章主要介紹“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)