來源:http://www.tianxiaboke.com/u/lyeerwy
級(jí)聯(lián)保存和更新
當(dāng)Hibernate持久化一個(gè)臨時(shí)對(duì)象時(shí),在默認(rèn)情下,他不會(huì)自動(dòng)持久化所關(guān)聯(lián)的其他臨時(shí)對(duì)象,如果希望當(dāng)持久化對(duì)象時(shí)把他所關(guān)聯(lián)的所有臨時(shí)對(duì)象進(jìn)行持久化的話:可以把 的cascade屬性設(shè)置為"save-update" ,cascade的默認(rèn)屬性值為none。
cascade:設(shè)置操作對(duì)象時(shí)的級(jí)聯(lián)操作,即層級(jí)之間的連鎖操作
值 save-update :表示當(dāng)保存和更新當(dāng)前對(duì)象(即insert和update語句時(shí)),會(huì)級(jí)聯(lián)保存和更新與他關(guān)聯(lián)的對(duì)象
值 all :表示任何情況下都會(huì)進(jìn)行級(jí)聯(lián)操作,即對(duì)一個(gè)對(duì)象進(jìn)行操作,也會(huì)對(duì)和他關(guān)聯(lián)的其他對(duì)象進(jìn)行同樣的操作
值 delete :表示在執(zhí)行delete時(shí),進(jìn)行級(jí)聯(lián)操作,刪除和他關(guān)聯(lián)的對(duì)象
值 none :表示任何情況下,都不會(huì)進(jìn)行級(jí)聯(lián)操作
<set>元素的inverse屬性
在運(yùn)行上面的程序時(shí),如果hibernate的"show-sql"設(shè)置為true時(shí),就會(huì)看到Hibernate會(huì)生成很多sql語句,其實(shí)很多sql語句都是重復(fù)的
eg:
insert into test.order(o_name,c_id)values(?,?)
insert into test.order(o_name,c_id)values(?,?)
insert into test order set c_id=? where id=?
insert into test order set c_id=? where id=?
為了解決這個(gè)問題,我們可以利用在<set>標(biāo)簽中加上inverse屬性。術(shù)語:inverse是指反轉(zhuǎn)的意思,在 Hibernate中,表示關(guān)聯(lián)關(guān)系中的方向關(guān)聯(lián)關(guān)系中,inverse="false"的主控方,由主動(dòng)方負(fù)責(zé)維護(hù)對(duì)象關(guān)系我們 在customer對(duì)象的對(duì)象配置文件中加上
<set name="orders" cascade="save-update" inverse="true">
<key column="c_id" > </key>
<one-to-many class="net.mbs.mypack.Order " />
</set>
聲明在Customer和Order的雙向關(guān)聯(lián)關(guān)系中,Customer端的關(guān)聯(lián)只是Order端關(guān)聯(lián)的鏡象(即Order端是主空端,負(fù)責(zé)維護(hù) Customer和order對(duì)象之間的關(guān)聯(lián)關(guān)系),當(dāng)hibernate探測(cè)到持久化對(duì)象Customer或Order的狀態(tài)發(fā)生變化時(shí)(主要是關(guān)聯(lián)關(guān)系的改變),僅按照Order對(duì)象的狀態(tài)的變化來同步更新數(shù)據(jù)庫。
按次配置,如果在程序中,我們僅僅使用Customer.getOrder().add(order)(涉及了和Order的關(guān)聯(lián)關(guān)系的改變),是不能讓數(shù)據(jù)庫跟對(duì)象的變化來進(jìn)行數(shù)據(jù)庫同步更新的,只有利用Order對(duì)象的方法改變的Order對(duì)象狀態(tài) (eg:order.setCustomer(customer)----涉及到了和Customer的關(guān)聯(lián)關(guān)系的改變)時(shí),數(shù)據(jù)庫才會(huì)根據(jù)變化來同步更新數(shù)據(jù)庫,即只有主控方的狀態(tài)(涉及到了和另一方面的關(guān)聯(lián)關(guān)系的改變)發(fā)生了變化后,才會(huì)觸發(fā)對(duì)象和數(shù)據(jù)庫的同步更新。
映射一對(duì)多雙向關(guān)聯(lián)關(guān)系
當(dāng)類與類之間建立了關(guān)聯(lián),就可以方便的從一個(gè)對(duì)象導(dǎo)航到另一個(gè)對(duì)象或一組與他關(guān)聯(lián)的對(duì)象當(dāng)中,根據(jù)上面的程序,對(duì)于一個(gè)給定的Order對(duì)象,如果想獲取與他關(guān)聯(lián)的Customer對(duì)象,我們只需要調(diào)用入下方法:
Customer c=order.geCustomer(); 那么當(dāng)我們得到一個(gè)Customer對(duì)象后,想查出和這個(gè)Customer對(duì)象關(guān)聯(lián)的所有Order對(duì)象時(shí),應(yīng)該怎么辦呢?由于在Customer中沒有建立對(duì)Order對(duì)象的關(guān)聯(lián),所以,不能通過加載Customer對(duì)象來自動(dòng)加載和他關(guān)聯(lián)的所有Order對(duì)象,唯一的方法只能通過JDBC或SQL語言人工寫出代碼來查詢數(shù)據(jù)庫Order表來返回所需要的信息
上面的問題雖然解決,但不能算是最好,因?yàn)檫@樣性能會(huì)有所下降,對(duì)象位于內(nèi)存中,在內(nèi)存中從一個(gè)對(duì)象導(dǎo)航到另一個(gè)對(duì)象顯然比到數(shù)據(jù)庫中查詢數(shù)據(jù)要快得多
具體實(shí)現(xiàn)<br>
1:由于Customer和Order是一對(duì)多,即一個(gè)Customer要對(duì)應(yīng)多個(gè)Order,所以在Customer中應(yīng)該建立一個(gè)Set對(duì)象,用于存放和本Customer對(duì)象關(guān)聯(lián)的所有Order對(duì)象。
2:在customer.hbm.xml通過<one-to-many>建立對(duì)Order表的關(guān)聯(lián)關(guān)系
注意:<one-to-many>應(yīng)該放置在<set>標(biāo)簽中
我們先來看看Customer類的設(shè)計(jì)和customer.hbm.xml文件的內(nèi)容
<br><br><br>------------------------------------------------------
Customer Order 雙向一對(duì)多
1:Customer類中建立一個(gè)容器對(duì)象,包含關(guān)聯(lián)的所有Order對(duì)象
2:Order類中建立一個(gè)Customer對(duì)象,關(guān)聯(lián)Customer
inverse="true"表示將維護(hù)關(guān)聯(lián)的權(quán)利交給引起Hibernate語句的生成
customer.getOrders().add(order);
customer.setName("dddddd");
inverse="true"(設(shè)置此屬性的一方----是被控方)
當(dāng)主控方修改對(duì)象之間的關(guān)聯(lián)關(guān)系時(shí),讓Hibernate生成sql語句