資源描述:
《hibernate in action學(xué)習(xí)筆記》由會(huì)員上傳分享,免費(fèi)在線閱讀,更多相關(guān)內(nèi)容在教育資源-天天文庫。
1、Hibernateinaction學(xué)習(xí)筆記第一章理解O/R持久化一,常見的設(shè)計(jì)難點(diǎn):用一個(gè)User和BillingDetails的例子來解釋;User有多個(gè)Bill,User里面有User的相關(guān)信息,包括name,address等等,BillingDetails中用User的主鍵作為外鍵。1,粒度問題比如User的Adrress字段包括了city,street,zipcode等等信息,在Java中可以用一個(gè)Address類來持有這些信息,然而在數(shù)據(jù)庫中情況就不一樣了;最直接的是現(xiàn)在的數(shù)據(jù)庫大多都支持的UDT(user-definedcolum
2、ntypes),可以將Address作為一個(gè)整體存入到數(shù)據(jù)庫中,但是這樣的類型在不同數(shù)據(jù)庫中很難移植,所以在實(shí)踐中很少用這樣的方法;通常的做法是在數(shù)據(jù)庫中將Address的條目都作為單獨(dú)的column,比如ADDRESS_CITY。相比較而言,數(shù)據(jù)庫只能表現(xiàn)出兩層的粒度關(guān)系,顯然不如Java的類型更加靈活。(書3.5)2,子類型問題(書3.6)Java中我們經(jīng)常會(huì)用到繼承,我們擴(kuò)展一下上面的例子,我們?yōu)锽illingDetails類擴(kuò)展出一些子類:CreditCard,DirectDebit,Cheque等等。我們需要建立幾個(gè)不同的table
3、來存儲(chǔ)這些子類,然而數(shù)據(jù)庫卻并不支持它們之間的繼承關(guān)系;一個(gè)標(biāo)準(zhǔn)的外鍵依賴嚴(yán)格地對(duì)應(yīng)一個(gè)table,我們無法直接用一個(gè)外鍵對(duì)應(yīng)多個(gè)表。3,標(biāo)識(shí)問題(書3.45.0)顯然對(duì)于我們的User表,使用Username作為主鍵是一種很壞的設(shè)計(jì),尤其當(dāng)我們可能會(huì)改變username的時(shí)候,一般,我們會(huì)增加一個(gè)字段UserID來作為主鍵和外鍵使用。如何將這個(gè)字段對(duì)應(yīng)到j(luò)ava中也是一個(gè)問題。Java中通常會(huì)用==和equals()來判斷兩個(gè)對(duì)象是否相同,很多時(shí)候,會(huì)有多個(gè)不恒等的對(duì)象對(duì)應(yīng)于數(shù)據(jù)庫中同一條數(shù)據(jù),如何正確的equals()就是一個(gè)問題。4,如
4、何關(guān)聯(lián)的問題(書3.06.0)接下來我們關(guān)注一下映射和處理classes之間的關(guān)系到數(shù)據(jù)庫中,所有的外鍵都是必需的么?在我們的例子中,Address,User,BillingDetails三個(gè)Class是關(guān)聯(lián)的,然而在數(shù)據(jù)庫中,不同的是BillingDetails獨(dú)自一個(gè)表,而Address則不是。關(guān)聯(lián)的映射和實(shí)體關(guān)聯(lián)的管理在任何對(duì)象持久化的方案中都是中心的概念。面向?qū)ο蟮恼Z言使用對(duì)象引用和Collection來表現(xiàn)關(guān)聯(lián)(association)。而在關(guān)系數(shù)據(jù)庫中,關(guān)聯(lián)是用foreignkey來表示的。對(duì)象的引用本身具有方向性,如果兩個(gè)obj
5、ect有雙向的關(guān)聯(lián),你就必須在兩個(gè)object中都定義這種聯(lián)系,比如在User中:privateSetbillingDetails;而在BillingDetails中:privateUseruser;Java中可能會(huì)有many-to-many的關(guān)聯(lián),而數(shù)據(jù)表之間只可能有one-to-many和one-to-one的關(guān)聯(lián);如果你想在數(shù)據(jù)庫中表現(xiàn)一個(gè)many-to-many的關(guān)聯(lián),則你需要引進(jìn)一個(gè)新的聯(lián)接表,這張表在對(duì)象模型中沒有相應(yīng)的表現(xiàn),比如一個(gè)USER_BILLINGDETAILS表。1,objectgraphnavigation的問題(書
6、4.07.0)在Java中,如果你要訪問某個(gè)User的billing的信息,你會(huì)這樣子做:someUser.getBillingDetails().getAccountNumber();這在面向?qū)ο笾泻茏匀?,通常被叫做“walkingtheobjectgraph”。然而在SQL數(shù)據(jù)庫中,這樣子就不是一種有效的方法;提高數(shù)據(jù)訪問效率的最簡(jiǎn)單重要的一點(diǎn)就是盡可能減少對(duì)數(shù)據(jù)庫的request次數(shù),也就是減少SQL查詢的次數(shù),(也可以使用存儲(chǔ)過程和JDBCbatchAPI)。通常有效的對(duì)關(guān)聯(lián)數(shù)據(jù)的查詢是通過使用不同表之間的join來進(jìn)行的,多少個(gè)表進(jìn)
7、行join取決于你訪問對(duì)象的深度,比如:select*fromUSERuleftouterjoinBILLING_DETAILSbdon…..總結(jié):解決上面的問題需要花費(fèi)相當(dāng)?shù)臅r(shí)間和精力,根據(jù)經(jīng)驗(yàn),在一個(gè)Java應(yīng)用中30%以上的代碼是用來解決這些單調(diào)乏味的SQL/JDBC相關(guān)工作。二,持久層和其他在中大型的項(xiàng)目中,通常會(huì)按照職能組織classes,持久層就是其中之一。其他的關(guān)注層有表示,工作流,業(yè)務(wù)邏輯。還有所謂的“橫切”關(guān)注,橫切關(guān)注多半會(huì)被框架代碼所實(shí)現(xiàn)。典型的橫切關(guān)注有l(wèi)ogging,authorization,transaction
8、等等。通常最好的做法是把所有與持久化相關(guān)的類和組件組織在一起,在多層系統(tǒng)構(gòu)架中成為一個(gè)獨(dú)立的持久層。我們接下來會(huì)先看看這種多層的構(gòu)架以及為什么使用它,然后我們關(guān)注一