Hibernate優(yōu)化共15頁文檔_第1頁
Hibernate優(yōu)化共15頁文檔_第2頁
Hibernate優(yōu)化共15頁文檔_第3頁
Hibernate優(yōu)化共15頁文檔_第4頁
Hibernate優(yōu)化共15頁文檔_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、1. 抓取優(yōu)化抓取是指 Hibernate 如何在關(guān)聯(lián)關(guān)系之間進行導(dǎo)航的時候, Hibernate 如何獲取關(guān)聯(lián)對象的策略,其主要定義了兩個方面:如何抓取和何時抓取。1)如何抓取。Hibernate3 主要有兩種抓取方式,分別應(yīng)用于對象關(guān)聯(lián)實例(many-to-one、one-to-one)和對象關(guān)聯(lián)集合(set、map等),總共是四種變種:JOIN抓取: 通過在SELECT語句中使用OUTER JOIN獲得對象的關(guān)聯(lián)實例或者關(guān)聯(lián)集合)SELECT?。毫硗獍l(fā)送一條SELECT語句來抓取當(dāng)前對象的關(guān)聯(lián)實體和集合在我的開發(fā)經(jīng)歷中,此處對性能的優(yōu)化是比較有限的,并不值得過多關(guān)注例:A. 應(yīng)用于對象關(guān)

2、聯(lián)實例(默認(rèn)是false )<many-to-one name="." outer-join="true/false/auto"./>B. 應(yīng)用于對象關(guān)聯(lián)集合(默認(rèn)是auto )<set name="." fetch="join/select" . ></set>2)何時抓取主要分為 延遲加載和立即抓取 ,默認(rèn)的情況下 Hibernate3 對對象關(guān)聯(lián) 實采用延遲加載, 普通屬性采用立即抓取 ,通過延遲加載和采用適當(dāng)?shù)淖ト×6?,與不采用優(yōu)化相 比往往可以將性能提升數(shù)倍。立即抓取:

3、 當(dāng)抓取宿主對象時,同時抓取其關(guān)聯(lián)對象和關(guān)聯(lián)集以及屬性延遲加載:當(dāng)抓取宿主對象時,并不抓取其關(guān)聯(lián)對象,而是當(dāng)對其對象進行調(diào)用時才加載。例:A. 應(yīng)用于對象關(guān)聯(lián)實例(默認(rèn)是延遲加載)<many-to-one name="."lazy="true/false" ./>B. 應(yīng)用于對象關(guān)聯(lián)集合(默認(rèn)是延遲加載)<set name="." lazy="true/false" . ></set>對于延遲加載,需要注意的時,對延遲對象的使用必須在 Session 關(guān)閉之前進行, Hibern

4、ate 的 LazyInitalizationException 往往就是由于在 Session 的生命期外使用 了延遲加載的對象。當(dāng)我們進行Web開發(fā)時,可以使用OpenSessionInView模式,當(dāng)請求開始時打開session,當(dāng)請求響應(yīng)結(jié)束時才關(guān)閉session,不過,在使用OpenSessionInView 模式時,需要注意如果響應(yīng)時間比較長(業(yè)務(wù)比較復(fù)雜或者客戶端是低速網(wǎng)絡(luò)),將Session 資源(也就是數(shù)據(jù)庫的連接 )占用太久的話可以會導(dǎo)致資源耗盡。3)抓取粒度抓取粒度指的是對象在關(guān)聯(lián)關(guān)系之間被導(dǎo)航時一次預(yù)先加載的數(shù)量,Hibernate 程序的性能比較差往往就在于沒有對抓取

5、粒度仔細考慮, 當(dāng)加載一個列表并在列表中的每個對象中對其關(guān)聯(lián)進行導(dǎo)航時,往往導(dǎo)致N+1條SQL語句查詢。例:A. 應(yīng)用于對象關(guān)聯(lián)實例(默認(rèn)為 1),注意,對對象關(guān)聯(lián)實例的設(shè)置是在被關(guān)聯(lián)的對象之上的,譬如class UserGroup g;那么抓取粒度應(yīng)該在 Group 的配置文件之上,見下<class name="Group" table="group"batch-size="."></class>對該值并沒有一個約定俗成的值,根據(jù)情況而定,如果被關(guān)聯(lián)表數(shù)據(jù)比較少,則可以設(shè)置地小一些,3-20 ,如果比較大則可

6、以設(shè)到 30-50 ,注意的時候,并不是越多越好,當(dāng)其值超過 50 之后,對性能并沒有多大改善但卻無謂地消耗內(nèi)存假設(shè)有如下例子:List<User> users = query.list();如果有20個User,并對這20個User及其Group進行遍歷,如果不設(shè)置 batch-size (即batch-size="1"),則在最糟糕的情況下,需要1 + 20條SQL語句,如果設(shè)置batch-size="10",則最好的情況下只需要1 + 2條SQL語句。B. 應(yīng)用于對象關(guān)聯(lián)集合(默認(rèn)為 1)<set name=".&quo

7、t; batch-size="" . ></set>2. 二級緩存Hibernate 對數(shù)據(jù)的緩存包括兩個級: 一級緩存, 在 Session 的級別上進行, 主要是對象緩存, 以其 id 為鍵保存對象, 在 Session 的生命期間存在; 二級緩存, 在 SessionFactory 的級別上進行,有對象緩存和查詢緩存,查詢緩存以查詢條件為鍵保存查詢結(jié)果,在 SessionFactory 的生命期間存在。默認(rèn)地, Hibernate 只 啟用一級緩存,通過正確地使用二級緩存,往往可以獲得意想不到的性能。1)對象緩存:當(dāng)抓取一個對象之后, Hiberat

8、e 將其以 id 為鍵緩存起來,當(dāng)下次碰到抓取 id 相同的對象時,可以使用如下配置。方法 1:在緩存對象上配置<class .><cache useage="read-only/write/" regions="group" /></class>useage 表示使用什么類型的緩存,譬如只讀緩存、讀寫緩存等等(具體參見 Hibernate 參考指南),值得注意的時,有部分緩存在 Hibernate 的實現(xiàn)中不支持讀寫緩存,譬如 JBossCache 在 Hibernate 的實現(xiàn)中只是一種只讀緩存,具體緩存實現(xiàn)對緩存

9、類型的支持情況,可以參見 org.hibernate.cache 包regions 表示緩存分塊,大部分的緩存實現(xiàn)往往對緩存進行分塊,該部分是可選的,詳細參見各緩存實現(xiàn)。方法 2:在 hibernate.cfg.xml 中配置<cache class="." useage="." regions="."/>我認(rèn)為第二種更好,可以統(tǒng)一管理。2) 查詢緩存查詢時候?qū)⒉樵兘Y(jié)果以查詢條件為鍵保存起來,需要配置如下A. 在 hibernate.cfg.xml 中配置(啟用查詢緩存)vproperty name="hiber

10、nate.cache.use_query_cache">true</property>(前面的屬性名可參見常量org.hibernate.cfg.Enviroment.USE_QUERY_CACHE )。B.程序query.setCacheable(true);query.setCacheRegions(.);需要注意的是 ,查詢緩存與對象緩存 要結(jié)合更有效 , 因為查詢緩存僅緩存查詢結(jié)果列表的主鍵數(shù)據(jù)一般情況下在開發(fā)中, 對一些比較穩(wěn)定而又被頻繁引用的數(shù)據(jù), 譬如數(shù)據(jù) 字典之類的,將其進行二級緩存,對一些查詢條件和查詢數(shù)據(jù)變化不頻繁而又常常被使用的查詢,將其進行二

11、級緩存 。由于二級緩存是放在內(nèi)存中,而且 Hibernate 的緩存不是弱引用緩存(WeekReference),所以注意不要將大塊的數(shù)據(jù)放入其中,否則可能會被內(nèi)存造成比較大的壓力。3. 批量數(shù)據(jù)操作當(dāng)進行大批量數(shù)據(jù)操作(幾萬甚至幾十幾百萬)時,需要注意兩點,一,批量提交,二,及時清除不需要的一級緩存數(shù)據(jù)1) 所謂的批量提交,就是不要頻繁使用session的flush,每一次進行flush,Hibernate將P0數(shù)據(jù)于數(shù)據(jù)庫進行同步,對于海量級數(shù)據(jù)操作來說是性能災(zāi)難(同時提交幾千條數(shù)據(jù)和提交一條數(shù)據(jù) flush 一次性能差別可能會是幾十倍的差異)。一般將數(shù)據(jù)操作放在事務(wù)中,當(dāng)事務(wù)提交時Hib

12、ernate 自動幫你進行 flush 操作。2) 及時清除不需要的一級緩存數(shù)據(jù):由于Hibernate 默認(rèn)采用一級緩存,而在 session 的生命期間,所有數(shù)據(jù)抓取之后會放入一級緩存中,而當(dāng)數(shù)據(jù)規(guī)模比較龐大時,抓取 到內(nèi)存中的數(shù)據(jù)會讓內(nèi)存壓力非常大,一般分批操作數(shù)據(jù),被一次操作之后將一級緩存清除,譬如session.clear(User.class)4. 雜項dynamic-insert , dynamic-update ,動態(tài)插入和動態(tài)更新, 指的是讓 Hibernate 插入數(shù)據(jù)時僅插入非空數(shù)據(jù),當(dāng)修改數(shù)據(jù)時只修改變化的數(shù)據(jù),譬如對于class User id usernamepas

13、sword如果 u.id=1, u.username="ayufox",u.password=null ,那么如果不設(shè)置動態(tài)插入,則其 sql 語句是 insert into users(id, username, password) values (1, 'ayufox', ') ,如果設(shè)置則其 sql 語句是 insert into users(username) valeus('ayufox')在如上的情況下,如果修改 u.password='11' ,那么如果不設(shè)置動態(tài)更新,則 sql 語句為 update u

14、sers set username='ayufox', password='11' where id = 1,如果設(shè)置則為 update user set password='11' where d = 1設(shè)置是在 class 的映射文件中,如下<class name="User" table="users" dynamic=insert="true/false" dynamic-update="true/false" .></class>該設(shè)

15、置對性能的提升比較有限Hibernate 優(yōu)化方案一、 批量修改和刪除在 Hibernate 2 中,如果需要對任何數(shù)據(jù)進行修改和刪除操作,都需要先執(zhí)行查詢操作,在得到要修改或者刪除的數(shù)據(jù)后,再對該數(shù)據(jù)進行相應(yīng)的操作處理。在數(shù)據(jù)量少的情況下采用這種處理方式?jīng)]有問題,但需要處理大量數(shù)據(jù)的時候就可能存在以下的問題:占用大量的內(nèi)存。需要多次執(zhí)行 update/delete 語句,而每次執(zhí)行只能處理一條數(shù)據(jù)。以上兩個問題的出現(xiàn)會嚴(yán)重影響系統(tǒng)的性能。因此,在Hiber nate 3中引入了用于批量更新或者刪除數(shù)據(jù)的HQL語句。這樣,開發(fā)人員就可以一次更新或者刪除多條記錄,而不用每次都一個一個地修改或者刪

16、除記錄了。如果要刪除所有的 User對象(也就是User對象所對應(yīng)表中的記錄),則可以直接使用下面的 HQL語句:delete User而在執(zhí)行這個HQL語句時,需要調(diào)用 Query對象的executeUpdate()方法,具體的實例如下所示:String HQL="delete User"Query query=session.createQuery(HQL);int size=query.executeUpdate();采用這種方式進行數(shù)據(jù)的修改和刪除時與直接使用JDBC的方式在性能上相差無幾,是推薦使用的正確方法。如果不能采用HQL 語句進行大量數(shù)據(jù)的修改,也就是說只

17、能使用取出再修改的方式時,也會遇到批量插入時的內(nèi)存溢出問題,所以也要采用上面所提供的處理方法來進行類似的處理。二、使用SQL執(zhí)行批量操作在進行批量插入、修改和刪除操作時,直接使用JDBC來執(zhí)行原生態(tài)的SQL語句無疑會獲得最佳的性能,這是因為在處理的過程中省略或者簡化了以下處理內(nèi)容: HQL語句到SQL語句的轉(zhuǎn)換。 Java 對象的初始化。 Java 對象的緩存處理。但是在直接使用JDBC執(zhí)行SQL語句時,有一個最重要的問題就是要處理緩存中的Java對象。因為通過這種底層方式對數(shù)據(jù)的修改將不能通知緩存去進行相應(yīng)的更新操作,以保證緩存中的對象與數(shù)據(jù)庫中的數(shù)據(jù)是一致的。提升數(shù)據(jù)庫查詢的性能數(shù)據(jù)庫查詢

18、性能的提升也是涉及到開發(fā)中的各個階段,在開發(fā)中選用正確的查詢方法無疑是最基礎(chǔ)也最簡單的。1、SQL語句的優(yōu)化使用正確的SQL語句可以在很大程度上提高系統(tǒng)的查詢性能。獲得同樣數(shù)據(jù)而采用不同方式的SQL語句在性能上的差距可能是十分巨大的。由于Hibernate是對JDBC的封裝,SQL語句的產(chǎn)生都是動態(tài)由 Hibernate自動完成的。Hibernate 產(chǎn)生SQL語句的方式有兩種:一種是通過開發(fā)人員編寫的HQL語句來生成,另一種是依據(jù)開發(fā)人員對關(guān)聯(lián)對象的訪問來自動生成相應(yīng)的SQL語句。至于使用什么樣的SQL語句可以獲得更好的性能要依據(jù)數(shù)據(jù)庫的結(jié)構(gòu)以及所要獲取數(shù)據(jù)的具體情況來進行處理。在確定了所要

19、執(zhí)行的SQL語句后,可以通過以下三個方面來影響Hibernate所生成的SQL語句:HQL語句的書寫方法。查詢時所使用的查詢方法。對象關(guān)聯(lián)時所使用的抓取策略。2 、使用正確的查詢方法一種是得到單個持久化對象的 get() 方法和 load() 方法,另一種是 Query 對象的 list() 方法和 iterator() 方在前面已經(jīng)介紹過,執(zhí)行數(shù)據(jù)查詢功能的基本方法有兩種:法。 在開發(fā)中應(yīng)該依據(jù)不同的情況選用正確的方法。get() 方法和 load() 方法的區(qū)別在于對二級緩存的使用上。load() 方法會使用二級緩存,而 get() 方法在一級緩存沒有找到的情況下會直接查詢數(shù)據(jù)庫,不會去二

20、級緩存中查找。在使用中,對使用了二級緩存的對象進行查詢時最好使用load() 方法,以充分利用二級緩存來提高檢索的效率。list() 方法和 iterator() 方法之間的區(qū)別可以從以下幾個方面來進行比較。執(zhí)行的查詢不同list() 方法在執(zhí)行時,是直接運行查詢結(jié)果所需要的查詢語句,而 iterator() 方法則是先執(zhí)行得到對象 ID 的查詢,然后再根據(jù)每個 ID 值去取得所要查詢的對象。因此, 對于list()方式的查詢通常只會執(zhí)行一個SQL語句,而對于iterator。方法的查詢則可能需要執(zhí)行N+1條SQL語句(N為結(jié)果集中的記錄數(shù))。iterator。方法只是可能執(zhí)行 N+1條數(shù)據(jù),

21、具體執(zhí)行SQL語句的數(shù)量取決于緩存的情況以及對結(jié)果集的訪問情況。緩存的使用list() 方法 只能使用二級緩存中的查詢緩存,而無法使用二級緩存對單個對象的緩存 (但是會把查詢出的對象放入二級緩存中 ) 。所以,除非重復(fù)執(zhí)行相同的查詢操作, 否則無法利用緩存的機制來提高查詢的效率。iterator() 方法則可以充分利用二級緩存,在根據(jù) ID 檢索對象的時候會首先到緩存中查找,只有在找不到的情況下才會執(zhí)行相應(yīng)的查詢語句。所以,緩存中對象的存在 與否會影響到SQL語句的執(zhí)行數(shù)量。對于結(jié)果集的處理方法不同list() 方法會一次獲得所有的結(jié)果集對象, 而且它會依據(jù)查詢的結(jié)果初始化所有的結(jié)果集對象。

22、這在結(jié)果集非常大的時候必然會占據(jù)非常多的內(nèi)存, 甚至?xí)斐蓛?nèi)存溢出 情況的發(fā)生。iterator() 方法在執(zhí)行時不會一次初始化所有的對象,而是根據(jù)對結(jié)果集的訪問情況來初始化對象。因此在訪問中可以控制緩存中對象的數(shù)量,以避 免占用過多緩存, 導(dǎo)致內(nèi)存溢出情況的發(fā)生。使用 iterator() 方法的另外一個好處是,如果只需要結(jié)果集中的部分記錄,那么沒有被用到的結(jié)果對象根本 不會被初始化。所以,對結(jié)果集的訪 問情況也是調(diào)用iterator。方法時執(zhí)行數(shù)據(jù)庫SQL語句多少的一個因素。所以,在使用 Query 對象執(zhí)行數(shù)據(jù)查詢時應(yīng)該從以上幾個方面去考慮使用何種方法來執(zhí)行數(shù)據(jù)庫的查詢操作。四、 使用正

23、確的抓取策略所謂抓取策略(fetching strategy)是指當(dāng)應(yīng)用程序需要利用關(guān)聯(lián)關(guān)系進行對象獲取的時候,Hibernate獲取關(guān)聯(lián)對象的策略。抓取策略可以在0/R映射的元數(shù)據(jù)中聲明,也可以在特定的HQL或條件查詢中聲明。Hibernate 3 定義了以下幾種抓取策略。連接抓取 (Join fetching)連接抓取是指Hibernate在獲得關(guān)聯(lián)對象時會在 SELECT語句中使用外連接的方式來獲得關(guān)聯(lián)對象。查詢抓取 (Select fetching)查詢抓取是指Hibernate通過另外一條SELECTS句來抓取當(dāng)前對象的關(guān)聯(lián)對象的方式。這也是通過外鍵的方式來執(zhí)行數(shù)據(jù)庫的查詢。與連接抓

24、取的區(qū)別在于,通常情況下這個SELECT吾句不是立即執(zhí)行的,而是在訪問到關(guān)聯(lián)對象的時候才會執(zhí)行。子查詢抓取 (Subselect fetching)子查詢抓取也是指 Hibernate通過另外一條SELECT吾句來抓取當(dāng)前對象的關(guān)聯(lián)對象的方式。與查詢抓取的區(qū)別在于它所采用的SELECT吾句的方式為子查詢, 而不是通過外連接。批量抓取 (Batch fetching)批量抓取是對查詢抓取的優(yōu)化,它會依據(jù)主鍵或者外鍵的列表來通過單條SELECT吾句實現(xiàn)管理對象的批量抓取。以上介紹的是 Hibernate 3 所提供的抓取策略,也就是抓取關(guān)聯(lián)對象的手段。為了提升系統(tǒng)的性能,在抓取關(guān)聯(lián)對象的時機上,還

25、有以下一些選擇。立即抓取 (Immediate fetching)立即抓取是指宿主對象被加載時,它所關(guān)聯(lián)的對象也會被立即加載。延遲集合抓取 (Lazy collection fetching)延遲集合抓取是指在加載宿主對象時,并不立即加載它所關(guān)聯(lián)的對象,而是到應(yīng)用程序訪問關(guān)聯(lián)對象的時候才抓取關(guān)聯(lián)對象。這是集合關(guān)聯(lián)對象的默認(rèn)行為。延遲代理抓取 (Lazy proxy fetching)延遲代理抓取是指在返回單值關(guān)聯(lián)對象的情況下,并不在對其進行 get 操作時抓取,而是直到調(diào)用其某個方法的時候才會抓取這個對象。延遲屬性加載 (Lazy attribute fetching)延遲屬性加載是指在關(guān)聯(lián)對

26、象被訪問的時候才進行關(guān)聯(lián)對象的抓取。介紹了 Hibernate 所提供的關(guān)聯(lián)對象的抓取方法和抓取時機, 這兩個方面的因素都會影響 Hibernate 的抓取行為, 最重要的是要清楚這兩方面的影響是不同的, 不要將這 兩個因素混淆,在開發(fā)中要結(jié)合實際情況選用正確的抓取策略和合適的抓取時機。抓取時機的選擇在 Hibernate 3 中,對于集合類型的關(guān)聯(lián)在默認(rèn)情況下會使用延遲集合加載的抓取時機,而對于返回單值類型的關(guān)聯(lián)在默認(rèn)情況下會使用延遲代理抓取的抓取時機。對于立即抓取在開發(fā)中很少被用到,因為這很可能會造成不必要的數(shù)據(jù)庫操作,從而影響系統(tǒng)的性能。當(dāng)宿主對象和關(guān)聯(lián)對象總是被同時訪問的時候才有可能會

27、 用到這 種抓取時機。另外,使用立即連接抓取可以通過外連接來減少查詢SQL語句的數(shù)量,所以,也會在某些特殊的情況下使用。然而, 延遲加載又會面臨另外一個問題, 如果在 Session 關(guān)閉前關(guān)聯(lián)對象沒有被實例化, 那么在訪問關(guān)聯(lián)對象的時候就會拋出異常。 處理的方法就是在事務(wù)提交之前就完 成對關(guān)聯(lián)對象的訪問。所以, 在通常情況下都會使用延遲的方式來抓取關(guān)聯(lián)的對象。 因為每個立即抓取都會導(dǎo)致關(guān)聯(lián)對象的立即實例化, 太多的立即抓取關(guān)聯(lián)會導(dǎo)致大量的對象被實例化, 從而 占用過多的內(nèi)存資源。抓取策略的選取對于抓取策略的選取將影響到抓取關(guān)聯(lián)對象的方式,也就是抓取關(guān)聯(lián)對象時所執(zhí)行的SQL語句。這就要根據(jù)實際

28、的業(yè)務(wù)需求、數(shù)據(jù)的數(shù)量以及數(shù)據(jù)庫的結(jié)構(gòu)來進行選擇了。在這里需要注意的是,通常情況下都會在執(zhí)行查詢的時候針對每個查詢來指定對其合適的抓取策略。指定抓取策略的方法如下所示:User user = (User) session.createCriteria(User.class).setFetchMode("permissions", FetchMode.JOIN).add( Restrictions.idEq(userId) ).uniqueResult();五、 查詢性能提升小結(jié)在本小節(jié)中介紹了查詢性能提升的方法,關(guān)鍵是如何通過優(yōu)化 SQL語句來提升系統(tǒng)的查詢性能。 查詢方法

29、和抓取策略的影響也是通過執(zhí)行查詢方式和SQL語句的多少來改變系統(tǒng)的性能的。這些都屬于開發(fā)人員所應(yīng)該掌握的基本技能,避免由于開發(fā)不當(dāng)而導(dǎo)致系統(tǒng)性能的低下。在性能調(diào)整中,除了前面介紹的執(zhí)行 SQL語句的因素外,對于緩存的使用也會影響系統(tǒng)的性能。通常來說,緩存的使用會增加系統(tǒng)查詢的性能,而降低系統(tǒng)增力口、修改和刪除操作的性能 (因為要進行緩存的同步處理 )。所以,開發(fā)人員應(yīng)該能夠正確地使用有效的緩存來提高數(shù)據(jù)查詢的性能,而要避免濫用緩存而導(dǎo)致的系統(tǒng)性能變低。在采用緩存的時候也應(yīng)該注意調(diào)整自己的檢索策略和查詢方法,這三者配合起來才可以達到最優(yōu)的性能。另外,事務(wù)的使用策略也會影響到系統(tǒng)的性能。選取正確的

30、事務(wù)隔離級別以及使用。Hibernate 中二級緩存的配置和使用(一) Hibernate的二級緩存策略的一般過程如下:1)條件查詢的時候,總是發(fā)出一條 select * from table_name where.(選擇所有字段)這樣的SQL語句查詢數(shù)據(jù)庫, 一次獲得所有的數(shù)據(jù)對象。2)把獲得的所有數(shù)據(jù)對象根據(jù) ID 放入到第二級緩存中。3)當(dāng) Hibernate 根據(jù) ID 訪問數(shù)據(jù)對象的時候,首先從 Session 一級緩存中查;查不到,如果配置了二級緩存,那么從二級緩存中查;查不到,再查詢數(shù)據(jù)庫,把結(jié)果按照ID 放入到緩存。4)刪除、更新、增加數(shù)據(jù)的時候,同時更新緩存。Hibernat

31、e 的二級緩存策略,是針對于 ID 查詢的緩存策略,對于條件查詢則毫無作用。 為此, Hibernate 提供了針對條件查詢的 Query Cache 。(二)什么樣的數(shù)據(jù)適合存放到第二級緩存中?1 很少被修改的數(shù)據(jù)2 不是很重要的數(shù)據(jù),允許出現(xiàn)偶爾并發(fā)的數(shù)據(jù)3 不會被并發(fā)訪問的數(shù)據(jù)4 參考數(shù)據(jù) , 指的是供應(yīng)用參考的常量數(shù)據(jù),它的實例數(shù)目有限,它的實例會被許多其他類的實例引用,實例極少或者從來不會被修改。(三)不適合存放到第二級緩存的數(shù)據(jù)?1 經(jīng)常被修改的數(shù)據(jù)2 財務(wù)數(shù)據(jù),絕對不允許出現(xiàn)并發(fā)3 與其他應(yīng)用共享的數(shù)據(jù)。實踐部分:使用EhCache配置二級緩存:配置準(zhǔn)備:1)把 ehcache-

32、1.2.3.jar 加入到當(dāng)前應(yīng)用的 classpath 中。2)在hibernate.cfg.xml文件中加入 EhCache緩存插件的提供類。1. <!- 配置緩存插件->2. <propertyname="vider_class">3. org.hibernate.cache.EhCacheProvider4. </property>3)挎貝 ehcache.xml 文件到類路徑 ( 項目工程的 src 目錄下 ),這個文件在 Hibernate 安裝目錄的 etc 下。配置步驟:Hiberna

33、te 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。示例:以 category( 產(chǎn)品類別 ) 和 product( 產(chǎn)品 ) 的映射為例:1) 修改要配置緩存的那個持久化類的對象關(guān)系映射文件:1.Category.hbm.xml<?xml version="1.0" encoding="utf-8"?>Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。Hibern

34、ate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。2.<!DOCTYPE hibernate-mapping PUBLIC "-/Hibernate/HibernateMapping DTD 3.0/EN"Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。3."http:/hibernate.sourceforge/hibernate-mapping-3.0.dtd"

35、>Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。4.<hibernate-mapping>5.<class name="org.qiujy.domain.cachedemo.Category"table="categories">6.配置緩存 , 必須緊跟在 class 元素后面

36、7.對緩存中的 Category 對象采用讀寫型的并發(fā)訪問策略8.<cache usage="read-write"/>9.<id name="id" type="java.lang.Long">10.<column name="id" />11.<generator class="native" />12.</id>13.!-配置版本號 , 必須緊跟在 id 元素后面14.<version name="version&

37、quot; column="version" type="java.lang.Long"/>15.<property name="name" type="java.lang.String">16.<column name="name" length="32" not-null="true"/>17.</property>18.<property name="description" typ

38、e="java.lang.String">19.<column name="description" length="255"/>20.</property>21.<set name="products" table="products"cascade="all" inverse="true">22.!-Hibernate 只會緩存對象的簡單屬性的值23.要緩存集合屬性,必須在集合元素中也加入cache子元素24.

39、而Hibernate僅僅是把與當(dāng)前持久對象關(guān)聯(lián)的對象的OID存放到緩存中。25.如果希望把整個關(guān)聯(lián)的對象的所有數(shù)據(jù)都存入緩存26.則要在相應(yīng)關(guān)聯(lián)的對象的映射文件中配置cache 元素27.<cache usage="read-write"/>28.<key column="categoryId" not-null="true"/>29.<one-to-many class="org.qiujy.domain.cachedemo.Product"/>30.</set>3

40、1.</class>32.</hibernate-mapping>Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。Product.hbm.xmlHibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。Hibernate 允許在類和集合的

41、粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。1.<?xml version="1.0"encoding="utf-8"?>2.<!DOCTYPE hibernate-mapping PUBLIC "-/Hibernate/HibernateMapping DTD 3.0/EN"Hibernate 允許在類和集合的粒度上設(shè)置第二級緩存。在映射文件中,class和set元素都有一個cache子元素,這個子元素用來配置二級緩存。3."http:/

42、hibernate.sourceforge/hibernate-mapping-3.0.dtd">4.<hibernate-mapping>5.<class name="org.qiujy.domain.cachedemo.Product"table="products">6.<cache usage="read-write"/>7.<idname="id" type="java.lang.Long">8.<column na

43、me="id" />9.<generator class="native" />10.</id>11.<!-配置版本號 , 必須緊跟在 id 元素后面 ->12.<version name="version" column="version" type="java.lang.Long"/>13.<property name="name" type="java.lang.String">14.

44、<column name="name" length="32" not-null="true"/>15.</property>16.<property name="description" type="java.lang.String">17.<column name="description" length="255"/>18.</property>19.<property name=&q

45、uot;unitCost" type="java.lang.Double">20.<column name="unitCost" />21.</property>22.<property name="pubTime" type="java.util.Date">23.<column name="pubTime" not-null="true"/>24.</property>25.<many-to

46、-one name="category"26.column="categoryId"27.class="org.qiujy.domain.cachedemo.Category"28.cascade="save-update"29.not-null="true">30.</many-to-one>31.</class>32.</hibernate-mapping>2) 編輯 ehcache.xml 文件:1.<ehcache>2.<dis

47、kStore path="c:ehcache"/>3.<defaultCache4.maxElementsInMemory="10000"5.eternal="false"6.timeToIdleSeconds="120"7.timeToLiveSeconds="120"8.overflowToDisk="true"9.<!- 設(shè)置 Category 類的緩存的數(shù)據(jù)過期策略->10.<cache name="org.qiujy.doma

48、in.cachedemo.Category"11.maxElementsInMemory="100"12.eternal="true"13.timeToIdleSeconds="0"14.timeToLiveSeconds="0"15.overflowToDisk="false"16.<!-設(shè)置 Category 類的 products 集合的緩存的數(shù)據(jù)過期策略17.<cachename="org.qiujy.domain.cachedemo.Category.p

49、roducts"18.maxElementsInMemory="500"19.eternal="false"20.timeToIdleSeconds="300"21.timeToLiveSeconds="600"22.overflowToDisk="true"23.<cachename="org.qiujy.domain.cachedemo.Product"24.maxElementsInMemory="500"25.eternal=&qu

50、ot;false"26.timeToIdleSeconds="300"27.timeToLiveSeconds="600"28.overflowToDisk="true"29.</ehcache>在 Spring 托管的 Hibernate 中使用二級緩存1 在 spring 的配置文件中, hibernate 部分加入 xml 代碼 org.hibernate.cache.EhCacheProvider true2. 為HBM表設(shè)置cache策略xml代碼3 .在DAO中,調(diào)用find 方法查詢之前,設(shè)置使用緩

51、存 Java代碼getHibernateTemplate().setCacheQueries(true);補充: 如果不設(shè)置“查詢緩存”,那么 hibernate只會緩存使用 load() 方法獲得的單個持久化對象,如果想緩存使用 findall() 、list() 、 Iterator() 、createCriteria()、createQuery() 等方法獲得的數(shù)據(jù)結(jié)果集的話,就需要設(shè)置 hibernate.cache.use_query_cache true 才行。hibernate1. 在數(shù)據(jù)庫中條件查詢速度很慢的時候,如何優(yōu)化 ?(1). 建索引(2) . 減少表之間的關(guān)聯(lián)(3)

52、. 優(yōu)化 sql ,盡量讓 sql 很快定位數(shù)據(jù),不要讓 sql 做全表查詢,應(yīng)該走索引 , 把數(shù)據(jù)量大的表排在前面(4) . 簡化查詢字段,沒用的字段不要,已經(jīng)對返回結(jié)果的控制,盡量返回少量數(shù)據(jù)2. 在 hibernate 中進行多表查詢 ,每個表中各取幾個字段 ,也就是說查詢出來的結(jié)果集并沒有一個實體類與之對應(yīng) ,如何解決這個問題 ?解決方案一,按照 Object 數(shù)據(jù)取出數(shù)據(jù),然后自己組 bean解決方案二,對每個表的 bean 寫構(gòu)造函數(shù),比如表一要查出 field1,field2 兩個字段,那么有一個構(gòu)造函數(shù)就是 Bean(type1 filed1,type2 field2) ,然后

53、在 hql 里面就可 以直接生成這個 bean 了。具體怎么用請看相關(guān)文檔,我說的不是很清楚。hibernate 的核心類是什么,它們的相互關(guān)系是什么?重要的方法是什么 ?Configuration 接口:配置 Hibernate ,根據(jù)其啟動 hibernate ,創(chuàng)建 SessionFactory 對象;SessionFactory 接口:初始化 Hibernate ,充當(dāng)數(shù)據(jù)存儲源的代理,創(chuàng)建session 對象, sessionFactory 是線程安全的,意味著它的同一個實例可以被應(yīng) 用的多個線程共享,是重量級、二級緩存;第 10 頁Session 接口:負(fù)責(zé)保存、更新、刪除、加載和

54、查詢對象,是線程不安全的, 避免多個線程共享同一個 session ,是輕量級、一級緩存;Transaction 接口:管理事務(wù);Query 和 Criteria 接口:執(zhí)行數(shù)據(jù)庫的查詢。Session 如下方法Save/ load/Update/Delete/get/saveOrUpdate/deleteAllQuery q=CreateQuery( “from Customer where customerName=:customerName ”)beginTransactioncloseTransactionCommit()優(yōu)化 hibernate 性能的幾點建議1、針對oracle數(shù)據(jù)

55、庫而言,F(xiàn)etch Size 是設(shè)定JDBC的Statement讀取數(shù)據(jù)的時候每次從數(shù)據(jù)庫中取出的記錄條數(shù),一般設(shè)置為30、50、100。Oracle數(shù)據(jù)庫的JDBC驅(qū)動默認(rèn) 的 Fetch Size=15 ,設(shè)置 Fetch Size 設(shè)置為: 30、 50,性能會有明顯提升,如果繼續(xù)增大,超出 100,性能提升不明顯,反而會消耗內(nèi)存。即在 hibernate 配制文件中進行配制:Xml代碼1 v propertyname= hibernateProperties>2 v props >3 v propkey=”hibernate.dialect”> org.hiberna

56、te.dialect.Oracle9Dialectv /prop >4 v propkey=”hibernate.show_sql ”> false v /prop >when the JVM starts upCreate/update the database tables automatically> update v /prop >->6 v prop key=”hibernate.hbm2ddl.autoTurn batching off for bettererror messages under PostgreSQL8 v propkey=”h

57、ibernate.jdbc.batch_size”>100v/prop>->9 v propkey=”hibernate.jdbc.batch_size”>50v/prop>10 v/props >Xml代碼1. 1 vpropertyname=”hibernateProperties ”>第 11 頁2.2< props>3.3v propkey=”hibernate.dialect ”>org.hibernate.dialect.Oracle9Dialectv /prop >4.4v propkey=”hibernate.s

58、how_sql ”>falsev /prop >5.5v !-Create/updatethe databasetables automaticallywhenthe JVM startsup6.6v propkey=”hibernate.hbm2ddl.auto”>update v /prop >->7.7v !-Turnbatching off for bettererror messagesunderPostgreSQL8.8v propkey=”hibernate.jdbc.batch_size”> 100v /prop >->9.9v

59、propkey=”hibernate.jdbc.batch_size”> 50 v /prop >10.10v /props >11.< /property >Fetch Size 設(shè)的越大,讀數(shù)據(jù)庫的次數(shù)越少,速度越快; Fetch Size 越小,讀數(shù)據(jù)庫的次數(shù)越多,速度越慢。2、 如果是超大的系統(tǒng),建議生成htm 文件。加快頁面提升速度。3、不要把所有的責(zé)任推在 hibernate 上,對代碼進行重構(gòu),減少對數(shù)據(jù)庫的操作,盡量避免在數(shù)據(jù)庫查詢時使用 in 操作,以及避免遞歸查詢操作,代碼質(zhì)量、系統(tǒng)設(shè)計的合 理性決定系統(tǒng)性能的高低。4、 對大數(shù)據(jù)量查詢時,慎用 list() 或者 iterator() 返回查詢結(jié)果,(1) . 使用 List() 返回結(jié)果時, Hibernate 會所有查詢結(jié)果初始化為持久化對象,結(jié)果集較大時,會占用很多的處理時間。(2) . 而使用 iterator() 返回結(jié)果時,在每次調(diào)用 iterator.next() 返回對象并使用對象時, Hibernate 才調(diào)用查詢將對應(yīng)的對象初始 化,對于大數(shù)據(jù)量時,每調(diào)用一次查詢都會花費較多的時間。當(dāng)結(jié)果集較大,但是含有較大量相同的數(shù)據(jù),或者結(jié)果集不是全部都會使用時,使用iterator() 才有優(yōu)勢。5、 在一對多

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論