初觸hibernate--基礎知識盲區

eBusinessMan發表於2015-03-16

1.       三種狀態的理解:

Transient: new 的物件僅僅在記憶體中,沒有在session的快取

Persistent: new 的物件不僅僅在記憶體中,還在session的快取以及DB中(硬碟);

detached : new 的物件僅僅在記憶體中 和 DB 中,但是session的快取卻沒有.

2.       get:一旦執行就立馬生成sql語句去DB中取資料。

load:不會立馬生成sql語句去資料,而是先返回一個代理物件(其實是具體物件的子類,但是一定是覆蓋了父類的方法,這可以推理的),等需要去物件中的內容時,在生成sql語句去資料。因此在取物件中的內容之前,即使DB中沒有對應的記錄,它還不會報錯,因為sql語句沒有傳送,但是一旦去代理物件的內容時,就會發出sql語句,於是立馬報錯!(load的和get的區別還有:各自在生成sql取不存在的資料時,前者報錯,後者不會而返回null)。

注意:getload之前都會在快取中尋找是否已經存在了對應的物件,如果有的話,就都不會再傳送sql語句去DB中取。

3.       updatedelete會在commit時才傳送sql語句。save()會即時傳送sql語句。

delete()後,session快取中將會去掉對應的物件,但是此時還沒有commit,所以DB中還存在著對應的記錄,因為sql語句還沒有傳送。即物件將會從persist轉化為detached態。然而,此時

4.       持久態中的物件的屬性的每一個變化都會通過sql語句(update)同步到DB中,但是如果所有修改過的屬性的值和改變前的一樣(hibernate會對比的),就不會updateDB中;如果(有一個屬性)不同話,都會update,而且是所有欄位都給按照物件的對應屬性現在值update掉(就是不可以修改部分欄位)。

5.       session.update(Object):用起來非常死板,不可以修改部分欄位,因此還是HQL好點。

還有,update()一次只能更新一條記錄,而且如果在表中找不到要更新的row的話,就會報錯!(限制非常多)。

6.       注意使用session.update()的話,生成的update語句是在commit()中發出去的,因此無論在commit前修改多少次,都只會發出一次update語句來更新最後一次修改的值。都

如果想在commit()前每次都傳送一次update語句的話,就在兩次修改間使用session.flush()(強制傳送update語句)。

7.       如果只想update部分欄位,有三種方法:

l  在property中 加入:updatable=false,表示這個欄位是無法改變的,當然這是最笨的方法。

l  在class中 加入:dymatic-update=true,表示可以動態更新,就是可以更新部分欄位,但是這種方式只可以在同一個session中(可以對比而決定是否修改),卻無法跨session—因為當一個session close後,它就轉化成為detached,當再要通過它更新的話,就得在建立一個session,此時,又會變成更新所有欄位的形式,因為新的session中沒有快取這個物件,所以無法對比,所以還是全部欄位update。但是有一種方式可以避免這種情況,就是在新的session中使用merge(obj),就是將記錄和物件進行合併,就是將記錄中和物件中屬性的值不同的改為和物件的相同。然而,這合併前肯定有一個對比的過程,於是session還得將對應的記錄從DBselect出來然後再對比,這樣的話,就會多了一次查詢。

l  使用HQL吧,這是最好的。

8.       session.save()雖然將物件從transient轉化成persistent狀態,但是並非其全部的屬性(例如如果部分屬性是save前沒有設定值的)都變得和DB中對應欄位的值一致。

9.       每一次commit時,都會檢查此時需要udate的物件和剛get出來的物件的屬性上的不同,如果有不一致的屬性,就會發出update sql語句;如果沒有改變(即使過程中改變了很多次但是改到此時的屬性值依然和剛get出來的值一致),就不會傳送update語句。

10.    採用getCurrentSession()建立的session在commit或rollback時會自動關閉,而採用openSession(),建立的session必須手動關閉

11.    openSession():每次生成一個新的session物件,

getCurrentSession():從上下文中找,提高複用率。

12.    ID生成策略:常用的有:native(任意平臺),uuid(任意平臺),identity(主要mysql,對應auto_increment),sequence(oracle).

13.    建立聯合主鍵,

14.    cascade該屬性定義類和類之間的級聯關係。定義的級聯關係將被容器視為對當前類物件及其關聯類物件採取相同的操作,而且這種關係是遞迴呼叫的。舉個例子:Order 和OrderItem有級聯關係,那麼刪除Order時將同時刪除它所對應的OrderItem物件。而如果OrderItem還和其他的物件之間有級聯關係,那麼這樣的操作會一直遞迴執行下去。

15.    專案中Hibernate 介於程式和資料庫之間,會極大地減輕資料庫的負擔:由於hibernate的快取和事務管理,程式很多sql語句沒必要每一次都傳輸到DBMS中執行,這樣的話在高併發情況下,很多針對相同資料記錄的dml可以在hibernate的快取中完成,然後再適當時刻hibernate只需將最終的修改對映到資料庫中。當然這樣就會增添了程式的負擔。

16.    由於hibrenate的多型查詢的特點,所以PO之間千萬別存在繼承關係。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29900383/viewspace-1461660/,如需轉載,請註明出處,否則將追究法律責任。

相關文章