Hibernate性能調優

Hibernate性能調優

1 Hibernate 連接池

   hibernate自帶一個連接池,但是這個連接池的性能不好,BUG也比較多,所以hibernate藉助第三方的連接池來配置。通常用的比較多的是prxool。目前在j2ee中最通用的框架ssh中,hibernate的配置如下:

 spring applicationContext.xm.配置文件裏配置數據源連接信息:

<!-- 配置數據源 -->

   <bean id="dataSource"

class="org.springframework.jdbc.datasource.DriverManagerDataSource">

     <property name="driverClassName">

   <value>org.logicalcobwebs.proxool.ProxoolDriver</value>

     </property>

     <property name="url">

        <value>proxool.spring_user</value>

     </property>

   </bean>

  web.xml中做如下配置

<!-- 制定proxool.xml放置的位置 -->

     <param-value>WEB-INF/proxool.xml</param-value>

   </context-param>

   <listener>

proxool.xml連接池配置文件放入到工程裏WEB-INF目錄下,其中proxool.xml的內容如下:

<?xml version="1.0" encoding="utf-8"?>   

 <!-- theproxool configuration can be embedded within your own application's.    

 Anything outside the "proxool" tagis ignored. -->   

 <something-else-entirely>   

     <proxool>   

         <alias>spring_user</alias>

      <driver-url>jdbc:mysql://192.168.1.150:3306/chiyuweb</driver-url>   

         <driver-class>com.mysql.jdbc.Driver</driver-class>   

         <driver-properties>   

             <property name="user"value="root" />   

             <property name="password"value="123456" />   

             <property name="useUnicode"value="true" />   

             <property name="characterEncoding"value="GBK" />   

         </driver-properties>   

        <minimum-connection-count>5</minimum-connection-count>            <maximum-connection-count>50</maximum-connection-count>           <maximum-active-time>60000</maximum-active-time>   

         <house-keeping-test-sql>select 1</house-keeping-test-sql>   

         <prototype-count>5</prototype-count>   

         <house-keeping-sleep-time>60000</house-keeping-sleep-time>   

     </proxool>   

 </something-else-entirely>

 注:在prxool這個文件裏<alias>spring_user</alias> 表示連接的別名,一個連接池可以配置多個連接。

2 Hibernate 多條件分頁查詢

   Hibernate的多條件查詢的方法有很多種,比較常用的有兩種,一種的創建Query對象,一種是創建Criteria對象。

    Query對象查詢:Hibernate上下文對象query= session.createQuery(HQL); query.setParameters(Object[]params,Type[] types)返回一個根據參數查詢的List集合。分頁方法query.setFirstResult(START),START參數表示從查詢到的結果集裏第幾條記錄開始取query.setMaxResults(ROWS),ROWS表示分頁信息中每頁查詢的記錄條數。根據如上方法即可以實現hibernate多條件分頁查詢。其中query.setParameters方法的兩個參數,params,types。他們是一一對應,成對出現的,所以最後用順序表來保存他們的值,即兩個用ArrayList來成對存儲兩個參數,然後將他們轉化成數組。Type類型是org.hibernate中的Type類。如果參數是String類型,則參數需要設置成Hibernate.STRING,如他類型依次類推。時間類型需要注意如果比較精確到天,類型可設置成Hibernate.DATE,如果時間要精確到秒,則時間類型需要設置成Hibernate.TIMESTAMPS.

      Criteria對象查詢,調用session.createCriteria(Typetype).add() type是反射包裏面的Type ,(若查User類 ,則傳入User.class),add()方法能夠傳入字段的名稱 addOrder方法能夠傳入排序規則,如此實現多條件查詢。分頁方法同query。

3Hibernate關聯關係

Hibernate通常用的關聯關係有三種:一對一,一對多和多對多。

一對一的方式有兩種:一種是聯合主鍵;一種是通過其他列來關聯,即多對一的特殊形式,將多對一unique屬性設置爲true。配置方法網上都有這裏就不囉嗦。

     多對多關係並不提倡用many-to-many方式來配,通常用兩個一對多的關係來實現。

      一對多關係,這個關係的配的時候要特別注意,在多的一方<many-to-one/> 這邊的lazy屬性一般不要設置爲false。這樣配會大大的降低程序的性能。還有就是關聯的列最好不要設置成外鍵關係,以爲這樣做加了外鍵會使數據庫不易維護。關聯列單獨設置,在實體配置文件中這個列的約束這樣設置 insert=”false” update=”false” 即可。

對於一對多自連接關係舉一個實例來說明:

比如一個Person類裏有老師和學生的關係

則Person.hbm.xml配置如下

<property name=”teacher_id” type=”java.lang.Integer” insert=”false” update=”false” />

<set name="students" cascade="save-update" inverse="true" lazy="true">

     <key column="teacher_id" />

        <one-to-many class="Person" />

     </set>

   <many-to-onename="student" column="teacher_id"

        class="Person" cascade="save-update"/>

 

 

2.二級緩存
 
   Hibernate對數據的緩存包括兩個級:一級緩存,在Session的級別上進行,主要是對象緩存,以其id爲鍵保存對象,在Session的生命期間存在;二級緩存,在SessionFactory的級別上進行,有對象緩存和查詢緩存,查詢緩存以查詢條件爲鍵保存查詢結果,在SessionFactory的生命期間存在。默認地,Hibernate只啓用一級緩存,通過正確地使用二級緩存,往往可以獲得意想不到的性能。
    1
)對象緩存:
    
當抓取一個對象之後,Hiberate將其以id爲鍵緩存起來,當下次碰到抓取id相同的對象時,可以使用如下配置
    
方法1:在緩存對象上配置
    <class ...>
       <cache useage="read-only/write/...." regions="group" />
    </class>
    useage
表示使用什麼類型的緩存,譬如只讀緩存、讀寫緩存等等(具體參見Hibernate參考指南),值得注意的時,有部分緩存在Hibernate的實現中不支持讀寫緩存,譬如 JBossCache在Hibernate的實現中只是一種只讀緩存,具體緩存實現對緩存類型的支持情況,可以參見org.hibernate.cache
    regions
表示緩存分塊,大部分的緩存實現往往對緩存進行分塊,該部分是可選的,詳細參見各緩存實現
    
方法2:在hibernate.cfg.xml中配置
    <cache class=".." useage=".." regions=".."/>
    
我認爲第二種更好,可以統一管理
    2)
查詢緩存
    
查詢時候將查詢結果以查詢條件爲鍵保存起來,需要配置如下
    A.
在hibernate.cfg.xml中配置(啓用查詢緩存)
    <property name="hibernate.cache.use_query_cache">true</property>  
(前面的屬性名可參見常量
org.hibernate.cfg.Enviroment.USE_QUERY_CACHE

    B.
程序
    query.setCacheable(true);
    query.setCacheRegions(...);
    
需要注意的是,查詢緩存與對象緩存要結合更有效,因爲查詢緩存僅緩存查詢結果列表的主鍵數據
    
一 般情況下在開發中,對一些比較穩定而又被頻繁引用的數據,譬如數據字典之類的,將其進行二級緩存,對一些查詢條件和查詢數據變化不頻繁而又常常被使用的查詢,將其進行二級緩存。由於二級緩存是放在內存中,而且Hibernate的緩存不是弱引用緩存(WeekReference),所以注意不要將大塊的數 據放入其中,否則可能會被內存造成比較大的壓力。
    3.
批量數據操作
    
當進行大批量數據操作(幾萬甚至幾十幾百萬)時,需要注意兩點,一,批量提交,二,及時清除不需要的一級緩存數據
    1
) 所謂的批量提交,就是不要頻繁使用session的flush,每一次進行flush,Hibernate將PO數據於數據庫進行同步,對於海量級數據操 作來說是性能災難(同時提交幾千條數據和提交一條數據flush一次性能差別可能會是幾十倍的差異)。一般將數據操作放在事務中,當事務提交時Hibernate自動幫你進行flush操作。
    2
)及時清除不需要的一級緩存數據:由於Hibernate默認採用一級緩存,而在session的生命期間,所有數據抓取之後會放入一級緩存中,而當數據規模比較龐大時,抓取到內存中的數據會讓內存壓力非常大,一般分批操作數據,被一次操作之後將一級緩存清除,譬如
    session.clear(User.class)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章