JPA緩存


1.概述

   對於JPA2.0,緩存分為一級緩存和二級緩存(JPA1.0只支持一級緩存)。

   二級緩存通常是用來提高應用程序性能的,它可以避免訪問以已經從數據庫加載的數據,提高訪問未被修改數據對象的速度

   持久化上下文就是JPA的一級緩存,通過在持久化上下文中存儲持久化狀態實體的快照,既可以進行臟檢測

   還可以當做持久化實體的緩存。一級緩存屬於請求范圍級別的緩存,如下

   

 

   注:一級緩存只是一個實體對象的持久化

   JPA二級緩存是跨越持久化上下文的,是真正意義上的全局應用緩存,如下

    

 

    注:

      第一點:如果二級緩存激活,JPA會先從一級緩存中尋找實體,未找到再從二級緩存中尋找。

                    當二級緩存有效時,就不能依靠事務來保護並發的數據,而是依靠鎖策略,如在確認修改后,需要手工處理樂觀鎖失敗等。

      第二點:二級緩存只能緩存通過EntityManager的find或getReference查詢到的實體

                    以及通過實體的getter方法獲取到的關聯實體;而不能緩存通過JPQL查詢獲得的數據。--也就是說緩存是通過容器的方式

     第三點:二級緩存通常用來提高性能,同時,使用二級緩存可能會導致提取到“陳舊”數據,

                   也會出現並發寫的問題。所以二級緩存最好是用在經常閱讀數據,比較少更新數據的情況,而不應該對重要數據使用二級緩存。

    

 

2.開啟二級緩存(對於不同的JPA實現產品,開啟二級緩存的方式會有所不同)

   Spring+Hibernate(最常用的)

        第一步:添加hibernate-ehcache.jar文件,推薦使用maven來管理;

        第二步:修改Spring配置文件,開啟二級緩存

        第三步:將需要緩存的實體類標注@ javax.persistence.Cacheable或org.hibernate.annotations.Cache。

          第一種 :@Cacheable配置

            采用@javax.persistence.Cacheable配置,開啟二級緩存如下

            <!--jpa-->
          <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
                <property name="dataSource" ref="dataSource"/>
                <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
                <property name="persistenceUnitName" value="template"/>
               <property name="packagesToScan" value="org.ssl.template.model"/>
              <!---指定JPA適配器-->
             <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                    <property name="showSql" value="true" />
                    <property name="generateDdl" value="true"/>
               </bean>
          </property>
        <property name="jpaProperties">
             <props>
                   <prop key="hibernate.cache.use_second_level_cache">true</prop> 
                  <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
                  <!--設置sharedCache.mode為ENABLE_SELECTIVE時,在實體上添加@Cacheable就可以被緩存-->
                  <prop key="javax.persistence.sharedCache.mode">ENABLE_SELECTIVE</prop>
                  <!--輸出統計信息,在部署時需要關閉-->
                  <prop key="hibernate.generate_statistics">true</prop>
            </props>
        </property> 
    </bean>

    總結:

       第一點:實體上標注@cacheable時,需要設置javax.persistence.sharedCache.mode屬性值;

       第二點:javax.persistence.sharedCache.mode值可以為ENABLE_SELECTIVE(推薦值)、DISABLE_SELECTIVE、NONE、ALL;

            若為ENABLE_SELECTIVE,則只要添加@Cacheable注解的實體才會被緩存;

            若為DISABLE_SELECTIVE,則標注@Cacheable(value=false)的實體才被緩存;

            若為NONE,任何實體都不會被緩存,即使被@Cacheable標注;

            若為ALL,實體都會被緩存,即使沒有@Cacheable標注;

       第三點:開啟Hibernate的查詢緩存

             1.設置key="hibernate.cache.use_query_cache">true</prop> 

             2.需要在JPA查詢時采用@QueryHint來實現查詢緩存

                public interface DictDao {

                     // 通過@QueryHint來實現查詢緩存。
                    @QueryHints({@QueryHint(name = "org.hibernate.cacheable", value ="true")})
                     List<Dict>findAll();
                }

       

      第二種:@Cache配置

       采用org.hibernate.annotation.Cache配置時,設置如下:

       <!--jpa-->
      <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
           <property name="dataSource" ref="dataSource"/>
           <property name="persistenceXmlLocation" value="classpath:META-INF/persistence.xml"/>
           <property name="persistenceUnitName" value="template"/>
           <property name="packagesToScan" value="org.ssl.template.model"/>
           <!---指定JPA適配器-->
          <property name="jpaVendorAdapter">
                <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
                     <property name="showSql" value="true" />
                     <property name="generateDdl" value="true"/>
               </bean>
          </property>
          <property name="jpaProperties">
              <props>
               <prop key="hibernate.cache.use_second_level_cache">true</prop> <!--propkey 合並和分開是否都行可以嘗試下--> 
                  <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
                  <!--輸出統計信息,在部署時需要關閉-->
                  <prop key="hibernate.generate_statistics">true</prop>
             </props>
         </property> 
    </bean>

    采用@cache時,除了在實體上標注@Cache外,還需要添加ehcache.xml配置文件,如下

    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="ehcache.xsd">
       <defaultCache
             maxElementsInMemory="1000"
             eternal="false"
             timeToIdleSeconds="120"
             timeToLiveSeconds="180"
             overflowToDisk="false"
            memoryStoreEvictionPolicy="LRU"
             />
            
      <cache name="org.hibernate.cache.internal.StandardQueryCache"
        maxElementsInMemory="100"
        eternal="false"
        timeToIdleSeconds="120"
         timeToLiveSeconds="180"
        overflowToDisk="true" />
 
      <cache name="org.hibernate.cache.spi.UpdateTimestampsCache"
        maxElementsInMemory="100"
        eternal="false"
        timeToIdleSeconds="120"
         timeToLiveSeconds="180"
        overflowToDisk="false" />
 
       
     <!--單個實體的緩存設置,不設置采用默認設置-->
     <!--
     <cachename="org.ssl.template.model.Template"
           maxElementsInMemory="100"
            eternal="false"
           timeToIdleSeconds="120"
           timeToLiveSeconds="180"
           overflowToDisk="false"
           memoryStoreEvictionPolicy="LRU"
             />
      -->
   </ehcache>

   總結:

      第一點:Hibernate3.x與Hibernate4.x開啟二級緩存設置不同

            Hibernate4.x:

                <propkey="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>

            Hibernate3.x:

                 <prop key="hibernate.cache.provider_class ">org.hibernate.cache.EhCacheProvider</prop>

         第二點:在部署項目時,需要將調試信息關閉,如關閉顯示sql語句、關閉更新數據表、更改日志的輸出級別等。

                <prop key="hibernate.generate_statistics">true</prop>

 

學習來源:https://blog.csdn.net/sunshuolei/article/details/48065955

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM