亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        網(wǎng)上購物系統(tǒng)中信息檢索性能優(yōu)化研究

        2008-01-01 00:00:00
        商場(chǎng)現(xiàn)代化 2008年3期

        [摘要] 文中對(duì)Hibernate檢索策略中內(nèi)存浪費(fèi)的原因進(jìn)行了研究,提出了采用查詢緩存和集合過濾的方法進(jìn)行查詢優(yōu)化, 降低了訪問數(shù)據(jù)庫的頻率且避免了在數(shù)據(jù)查詢檢索過程中加載不需要的Java對(duì)象,從而降低了的內(nèi)存消耗。最后,通過查詢網(wǎng)上購物系統(tǒng)中客戶的定單記錄試驗(yàn)驗(yàn)證了優(yōu)化方式的有效性。

        [關(guān)鍵詞] Hibernate 查詢緩存 集合過濾 客戶 定單

        在分層的軟件架構(gòu)中持久化層封裝了所有數(shù)據(jù)訪問細(xì)節(jié),是對(duì)象-關(guān)系映射(ORM)的中間件,Hibernate是一種ORM中間件工具,它對(duì)JDBC API進(jìn)行了封裝,負(fù)責(zé)Java對(duì)象的持久化。Hibernate通過Session接口提供了基本的保存、更新、刪除和查詢,Session具有一個(gè)緩存,位于緩存中的對(duì)象處于持久化狀態(tài),它和數(shù)據(jù)庫中的相關(guān)記錄對(duì)應(yīng),Session能夠在某些時(shí)間點(diǎn)按照緩存中持久化對(duì)象的屬性變化來同步更新數(shù)據(jù)庫。在Session的緩存中存放的是相互關(guān)聯(lián)的對(duì)象圖。在默認(rèn)情況下,當(dāng)Hibernate從數(shù)據(jù)庫中加載Java對(duì)象時(shí),會(huì)同時(shí)加載所有關(guān)聯(lián)的Java對(duì)象,從而影響了系統(tǒng)的性能。本文以查詢網(wǎng)上購物系統(tǒng)中的客戶(Customer)和定單(Order)信息為例,介紹如何設(shè)置Hibernate的檢索策略,以優(yōu)化查詢性能。

        一、常用查詢方法

        設(shè)計(jì)兩個(gè)數(shù)據(jù)庫表, 表名為CUSTOMERS和ORDERS, 它們包含的基本字段及之間的關(guān)系如圖1:

        Hibernate查詢客戶和定單信息的步驟為:

        1.運(yùn)用反射機(jī)制,獲得customer對(duì)象的類型Customer.class。

        2.參考對(duì)象-關(guān)系映射元數(shù)據(jù),了解到和Customer類對(duì)應(yīng)的表為CUSTOMERS表,類Customer與類Order關(guān)聯(lián),類Order和ORDERS表對(duì)應(yīng),ORDERS表中外鍵CUSTOMER_ID參照CUSTOMERS表的主鍵ID。

        3.根據(jù)映射信息,生成SQL語句:

        select *from CUSTOMERS;

        select *from ORDERS where CUSTOMERS_ID=1。

        4.調(diào)用JDBC API,執(zhí)行以上SQL語句。Hibernate在檢索與Customer關(guān)聯(lián)的Order對(duì)象時(shí),使用默認(rèn)的立即檢索策略。這種檢索策略存在三大不足:

        (1)select語句的數(shù)目太多需要頻繁地訪問數(shù)據(jù)庫,會(huì)影響檢索性能。

        (2)在應(yīng)用邏輯只需要訪問Customer對(duì)象,而不需要訪問Order對(duì)象的場(chǎng)合,加載Order對(duì)象完全是多余的操作,這些多余的Order對(duì)象浪費(fèi)了許多內(nèi)存空間。

        (3)假定這個(gè)Customer對(duì)象與500個(gè)Order對(duì)象關(guān)聯(lián),就會(huì)加載500個(gè)Order對(duì)象。在實(shí)際應(yīng)用中往往只需要訪問Orders集合中的部分Order對(duì)象.例如訪問客戶定單金額大于100的Order對(duì)象,此時(shí)調(diào)用customer.getOrders().iterator()方法會(huì)影響運(yùn)行時(shí)性能.因?yàn)樗鼤?huì)加載應(yīng)用程序不需要訪問的Order對(duì)象。

        延遲檢索策略能避免多余加載應(yīng)用程序不需要訪問的關(guān)聯(lián)對(duì)象;但當(dāng)采用延遲檢索策略時(shí),應(yīng)用程序如果希望訪問游離狀態(tài)的代理類實(shí)例,必須保證它作持久化狀態(tài)時(shí)已經(jīng)被初始化。迫切左外連接檢索策略則利用SQL的外連接查詢功能能夠減少select語句的數(shù)目;但缺點(diǎn)在于可能會(huì)加載應(yīng)用程序不需要訪問的對(duì)象,浪費(fèi)許多內(nèi)存空間,更雜的數(shù)據(jù)庫表連接也會(huì)影響檢索性能。

        二、查詢性能優(yōu)化

        Hibernate主要可從以下兩方面來優(yōu)化查詢性能。

        1.使用查詢緩存降低訪問數(shù)據(jù)庫的頻率,減少select語句的數(shù)目;對(duì)于經(jīng)常使用的查詢語句如果啟用了查詢緩存.當(dāng)?shù)谝淮螆?zhí)行查詢語句時(shí),Hibernate會(huì)把查詢結(jié)果存放在第二級(jí)緩存中。以后再次執(zhí)行該查詢語句時(shí).只需從緩存中獲得查詢結(jié)果從而提高查詢性能。對(duì)查詢語句啟用查詢緩存的步驟如下:

        (1)配置第二級(jí)緩存,在Customer.hbm.xml和 Order.hbm.xml映射文件中分別為Customer類、Customer類的orders集合以及Order類設(shè)置第二級(jí)緩存,

        Customer.hbm.xml設(shè)置第二級(jí)緩存代碼:

        name=“orders”

        >

        Order.hbm.xml設(shè)置第二級(jí)緩存代碼:

        (2)在Hibernate的配置文件hibernate.properties中選用EHCache和設(shè)置查詢緩存屬性:

        hibernate.cache.provider_class=net.sf.hibernate.cache.EhCacheProvi

        Hibernate.cache.use_query_cache=ture

        (3)對(duì)于希望啟用查詢?cè)娴牟樵冋Z句.調(diào)用接口Query的setCacheable()方法:

        Query orderByMoneyQuery=session.createQuery(“from Order o where o.money>:money”);

        orderByMoneyQuery.setInteger(“money”, money);

        orderByMoneyQuery. setCacheable(true);

        如果希望更加精粒度地控制查詢?cè)?,可以設(shè)置緩存區(qū)域.

        orderByMoneyQuery.setCacheRegion(“orderQueries”);

        Hibernate提供了三種和查詢相關(guān)的緩存區(qū)域

        ①默認(rèn)的查詢緩存區(qū)域:net.sf. hibernate.cache.StandardQueryCache

        ②用戶自定義的查詢緩存區(qū)域:如“orderQueries”

        ③時(shí)間戳緩存區(qū)域: net.sf. hibernate.cache.UpdateTimestampCache

        默認(rèn)的查詢緩存區(qū)域以及用戶自定義的查詢緩存區(qū)域部用于存放查詢結(jié)果。而時(shí)間戳緩存區(qū)域存放了對(duì)與查詢結(jié)果相關(guān)的表進(jìn)行插入、更新或刪除操作的時(shí)間戳。Hibernate通過時(shí)間戳緩存區(qū)域來判斷被緩存的查詢結(jié)果是否過期,它的運(yùn)行過程如下:

        在T1時(shí)刻執(zhí)行查詢語句,把查詢結(jié)果存放在QueryCache域.該區(qū)域的時(shí)間戳為TI時(shí)刻。

        在T2時(shí)刻對(duì)與查詢結(jié)果相關(guān)的表進(jìn)行插入、更新或刪除操作。Hibernate把T2時(shí)刻存放在UpdateTimestampCache區(qū)域。

        在T3時(shí)刻執(zhí)行查詢語句前,先比較QueryCache區(qū)域的時(shí)間戳和UpdateTimestampCache區(qū)域的時(shí)間戳.如果T2>T1,那么就丟棄原先存放在QueryCache區(qū)域的查詢結(jié)果,重新到數(shù)據(jù)庫中查詢數(shù)據(jù)再把查詢結(jié)果存放在QueryCache區(qū)域;如果T2<T1,直接從QueryCache區(qū)域獲得查詢結(jié)果。

        由此可見,如果當(dāng)前應(yīng)用進(jìn)程對(duì)數(shù)據(jù)庫的相關(guān)數(shù)據(jù)做了修改,Hibernate會(huì)自動(dòng)刷新緩存的查詢結(jié)果。若其他應(yīng)用進(jìn)程對(duì)數(shù)據(jù)庫的相關(guān)數(shù)據(jù)做了修改,Hibernate無法監(jiān)測(cè)到這一變化,此時(shí)由應(yīng)用程序負(fù)責(zé)監(jiān)測(cè)這一變化(如通過發(fā)送和接收事件或消息機(jī)制),然后手工刷新查詢結(jié)果。Query接口的setForceCacheRefresh(true)方法允許手工刷新查詢結(jié)果,它使得Hibernate丟棄查詢緩存區(qū)域中已有的查詢結(jié)果,重新到數(shù)據(jù)庫中查詢數(shù)據(jù).再把查詢結(jié)果存放在查詢緩存區(qū)域中。

        2.使用集合過濾避免多余加載程序不需要訪問的數(shù)據(jù)

        使用集合過濾可以很好避免加載多余的Order對(duì)象,其主要代碼如下:

        List result=session.createFilter(customer.getOrders(),“where this.money>100 order by this.money”).list();

        Iterator it=result.iterator();

        While(it.hasNext()){

        Order order=(Order)it.next();

        ……

        }

        代碼中Session接口的createFilter方法用來過濾集合,它具有以下優(yōu)點(diǎn):

        (1)如果Customer對(duì)象orders集會(huì)已經(jīng)被初始化,為了保證Session的緩存中不會(huì)出現(xiàn)OID相同的Order對(duì)象,Query的list()方法不會(huì)再創(chuàng)建Order對(duì)象,僅僅返回已經(jīng)存在的Order對(duì)象的引用。其運(yùn)行時(shí)行為如圖2所示:

        (2)如果Customer對(duì)象的orders集合還沒有被初始化,Query的list()方法會(huì)創(chuàng)建相應(yīng)的Order對(duì)象。但是不會(huì)初始化Customer對(duì)象的orders集合。其運(yùn)行時(shí)行為如圖3所示:

        三、試驗(yàn)分析

        這里通過檢索某客戶定單金額大于100元的所有定單試驗(yàn)來驗(yàn)證改進(jìn)前后的性能情況。

        按照立即檢索策略我們一次從數(shù)據(jù)庫中讀取客戶ID=1的所有訂單(共500條記錄)中金額大于100元的所有記錄(共200條記錄),然后按照改進(jìn)后的方式我們從數(shù)據(jù)庫中讀取上述記錄??紤]到Java虛擬機(jī)的垃圾收集機(jī)制和降低試驗(yàn)誤差,兩種的檢索方式分別做五次,取平均值。開發(fā)軟件采jdk1.5.0+Tomcat5.0.24,數(shù)據(jù)庫采用MySQL5.0.2。

        結(jié)果如下:

        1.采用立即檢索策略

        第一次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:23065K、26643K,查詢結(jié)果占3578K;

        第二次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22990K、26662K,查詢結(jié)果占用3672K;

        第三次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22998K、26580K,查詢結(jié)果占用3590K;

        第四次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22967K、26597K,查詢結(jié)果占用3612K;

        第五次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22978K、26574K,查詢結(jié)果占用3596K;

        查詢結(jié)果平均內(nèi)存占用為3609K。

        2.同時(shí)采用查詢緩存和集合過濾檢索策略

        第一次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:23070K、24032K,查詢結(jié)果占用962K;

        第二次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:23012K、23909K,查詢結(jié)果占用897K;

        第三次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22993K、23949K,查詢結(jié)果占用956K;

        第四次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22812K、23747K,查詢結(jié)果占用935K;

        第五次查詢前、后Java虛擬機(jī)內(nèi)存占用率分別為:22991K、23904K,查詢結(jié)果占用913K;

        查詢結(jié)果平均內(nèi)存占用為932K。

        從試驗(yàn)結(jié)果可知:采用本文所述的方式進(jìn)行查詢優(yōu)化操作,節(jié)約了大量的內(nèi)存,當(dāng)進(jìn)行大量數(shù)據(jù)查詢時(shí),效果十分明顯。

        四、結(jié)語

        Hibernate在持久化過程中由于采用立即檢索策略,導(dǎo)致加載了不需要的Java 對(duì)象和頻繁訪問數(shù)據(jù)庫,占用了大量的內(nèi)存。采用本文介紹的查詢緩存和集合過濾檢索策略,可以解決立即檢索策略中存在的問題,并且沒有增加開發(fā)人員的工作量,是減少內(nèi)存消耗的有效方法。

        參考文獻(xiàn):

        [1]唐慕瑾徐伯慶孫國(guó)強(qiáng):Java 類的動(dòng)態(tài)裝載機(jī)制及其在設(shè)計(jì)模式中的應(yīng)用[J].上海理工大學(xué)學(xué)報(bào), 2004,26(1):80-84

        [2]孫衛(wèi)琴:精通HIBERNATE: Java對(duì)象持久化技術(shù)詳解[M].北京:電子工業(yè)出版社,2005

        [3]何錚陳志剛:對(duì)象/關(guān)系映射框架的研究與應(yīng)用[J].計(jì)算機(jī)工程與應(yīng)用, 2003,39 (26):188-191,194

        [4]Hibernate 官方網(wǎng)站. [EB/OL]http://www.hibernate.org

        日本精品极品视频在线| 欧洲熟妇色xxxx欧美老妇多毛 | 丰满少妇人妻无码专区| 国产自国产在线观看免费观看| 久久99精品久久久66| 国产高清大片一级黄色| 99久久免费视频色老| 欧美日韩精品| 亚洲AV肉丝网站一区二区无码| 国产成人久久精品二区三区| 人妻少妇精品中文字幕专区| 日韩av精品国产av精品| 亚洲制服无码一区二区三区| 久久这黄色精品免费久 | 日本国产精品高清在线| 国内永久福利在线视频图片| 怡红院免费的全部视频| 99久久超碰中文字幕伊人| 精品人妻午夜中文字幕av四季| 男女18禁啪啪无遮挡激烈网站 | 欧美性videos高清精品| 亚洲AV秘 片一区二区三区| 内射爆草少妇精品视频| 99久久精品免费观看国产| 91久久青青草原线免费| 日本福利视频免费久久久| 一区二区三区免费看日本| 一本一道av中文字幕无码| 久久亚洲高清观看| 男女一区视频在线观看| 凹凸国产熟女精品视频app| 粗了大了 整进去好爽视频| 久久国产精品男人的天堂av | 国产欧美va欧美va香蕉在| 国产精品户露av在线户外直播| 蜜桃av多人一区二区三区| 中文字幕人妻少妇伦伦| 一本色综合久久| 最新欧美一级视频| 国产丝袜美腿在线播放| 男女做爰猛烈啪啪吃奶动|