這篇文章主要介紹“Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xiàn)”,在日常操作中,相信很多人在Hibernate關(guān)聯(lián)關(guān)系怎么實(shí)現(xià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如下:
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
id>
property>
class>
Order.hbm.xml如下:
PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
id>
property>
name="customer" column="CUSTOMER_ID" class="mypack.Customer" not-null="true" /> class> hibernate-mapping> 在Order.hbm.xml中 的映射。 它包括如下屬性。 ● 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ì)象: (以下代碼并非是完整代碼,只是簡單把邏輯列出) 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ì)象,可以把 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)的字段,因此不能用 PUBLIC "-//Hibernate/Hibernate Mapping DTD 2.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd"> name="orders" cascade="save-update" > 它包括如下屬性: ● ● ● ● 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) 如果是加載持久化對(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)用程序的性能,那么解決的辦法是把 name="orders" cascade="save-update" inverse="ture" > 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è)Categoryhttp://weahome.cn/article/pcgije.html