国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Hibernate之二級緩存

2019-11-14 22:06:44
字體:
來源:轉載
供稿:網友
Hibernate之二級緩存

Hibernate緩存  緩存(Cache):計算機領域非常通用的概念。它介于應用程序和永久性數據存儲源(如硬盤上的文件或數據庫)之間,其作用是降低應用程序直接讀寫永久性數據存儲源的頻率,從而提高應用的運行性能。緩存中的數據時數據存儲源中數據的拷貝。緩存的物理介質通常是內存

Hibernate中提供了兩個級別的緩存  第一級別的緩存是session級別的緩存,它是屬于事務范圍的緩存。這一級別的緩存有Hibernate管理的  第二級別的緩存是SessionFactory級別的緩存,它是屬于進程范圍的緩存

SessionFactory級別的緩存  SessionFactory的緩存可以分為兩類:    內置緩存:Hibernate自帶的,不可卸載。通常在Hibernate的初始化階段,Hibernate會把映射元數據和預定義的SQL語句放到SessionFactory的緩存中,映射元數據是映射文件中數據(.hbm.xml文件中的數據)的復制。該內置緩存是只讀的。    外置緩存(二級緩存):一個可配置的緩存插件。在默認情況下,SessionFactory不會啟用這個緩存插件。外置緩存中的數據是數據庫數據的復制,外置緩存的物理介質可以是內存或硬盤

使用Hibernate的二級緩存  適合放入二級緩存中的數據:    很少被修改    不是很重要的數據,允許出現偶爾的并發問題  不適合放入二級緩存中的數據:    經常被修改    財務數據,絕對不允許出現并發問題    與其他應用程序共享的數據

Hibernate二級緩存的架構

二級緩存的并發訪問策略  兩個并發的事務同時訪問持久層的緩存的相同的數據時,也有可能出現各類并發問題  二級緩存可以設定一下4種類型的并發訪問策略,每一種訪問策略對應一種事務隔離級別    非嚴格讀寫(Nonstrict-read-write):不保證緩存與數據庫中數據的一致性,提高Read Uncommited事務隔離級別,對于極少被修改,而且允許臟讀的數據,可以采用這種策略    讀寫型(Read-write):提供Read Commited數據隔離級別。對于經常臟讀但是很少被修改的數據,可以采用這種隔離類型,因為它可以防止臟讀    事務型(Transaction):僅在受管理環境下適用。它提供了Repeatable Read事務隔離級別。對于經常讀但是很少被修改的數據,可以采用這種隔離類型。因為它可以防止臟讀和不可重復讀    只讀型(Read-only):提供Serializable數據隔離級別。對于從來不會被修改的數據,可以采用這種訪問策略

管理Hibernate的二級緩存  Hibernate的二級緩存時進程或集群范圍內的緩存  二級緩存是可配置的插件,Hibernate允許選用以下類型的緩存插件:    EHCache:可作為進程范圍內的緩存,存放數據的物理介質可以使用內存或硬盤,對Hibernate的查詢緩存提供了支持    OpenSymphony OSCache:可作為進程范圍內的緩存,存放數據的物理介質可以使用內存或硬盤,提供了豐富的緩存數據過期策略,對Hibernate的查詢緩存提供了支持    SwarmCache:可作為集群范圍內的緩存,但不支持Hibernate的查詢緩存    JBossCache:可作為集群范圍內的緩存,支持Hibernate的查詢緩存4中緩存插件的并發訪問策略(X代表支持,空白代表不支持)

Read-onlyNonstrict-read-writeRead-writeTransaction
EHCacheXXX
OpenSymphony OSCacheXXX
SwarmCacheXX
JBossCacheXX

配置進程范圍內的二級緩存  配置進程范圍內的二級緩存的步驟:    選擇合適的緩存插件:EHCache(jar包和配置文件),并修改配置文件-----(hibernate-release-4.3.7.Final/lib/optional/ehcache/*.jar和hibernate-release-4.3.7.Final/PRoject/etc/ehcache.xml)    在Hibernate的配置文件中啟用二級緩存并指定和EHCache對應的緩存適配器    選擇需要使用二級緩存的持久化類,設置它的二級緩存的并發訪問策略      <class>元素的cache子元素表明Hibernate會緩存對象的簡單屬性,但不會緩存集合屬性,若希望緩存集合屬性中的元素,必須在<set>元素中加入<cache>子元素      在Hibernate配置文件中通過<class-cache/>節點配置使用緩存

==================本次介紹以EHCache為例==================================

EHCache配置文件(ehcache.xml)介紹

  <diskStore>:指定一個目錄,當EHCache把數據寫到硬盤上時,將把數據寫到這個目錄下  <defaultCache>:設置緩存的默認數據過期策略  <cache>:設定具體的命名緩存的數據過期策略。每個命名緩存代表一個緩存區域  緩存區域(region):一個具有名稱的緩存塊,可以給每一個緩存塊設置不同的緩存策略。如果沒有設置任何的緩存區域,則所有被緩存的對象,都將使用默認的緩存策略。即:<defaultCache.../>  Hibernate在不同的緩存區域保存不同的類/集合    對于類而言,區域的名稱是類名。如:com.yl.domain.Customer    對于集合而言,區域的名稱是類名加屬性名。如:com.yl.domain.Customer.orders  cache元素的屬性    name:設置緩存的名字,它的取值為類的全限定名或類的集合的名字    maxInMemory:設置基于內存的緩存中可存放的對象最大數目    eternal:設置對象是否為永久的,true表示永不過期,此時將忽略timeToIdleSeconds和timeToLiveSeconds屬性;默認值是false    timeToIdleSeconds:設置對象空閑最長時間,以秒為單位,超過這個時間,對象過期,當對象過期時,EHCache會把它從緩存中清除。如果此值為0,表示對象可以無限期地處于空閑狀態    timeToLiveSeconds:設置對象生存最長時間,超過這個時間,對象過期。如果此值為0,表示對象可以無限期地存在于緩存中。該屬性值必須大于或等于timeToIdleSeconds屬性值    overflowToDisk:設置基于內在的緩存中的對象數目達到上線后,是否把溢出的對象寫到基于硬盤的緩存中

查詢緩存  對于經常使用的查詢語句,使用啟用了查詢緩存,當第一次執行查詢語句時,Hibernate會把查詢結果存放在查詢緩存中。以后再次執行該查詢語句時,只需從緩存中獲得查詢結果,從而提高查詢性能  查詢緩存使用于如下場合:    應用程序運行時經常使用查詢語句    很少對于查詢語句檢索到的數據進行插入、刪除和更新操作  啟用查詢緩存的步驟:    配置二級緩存,因為查詢緩存依賴于二級緩存    在Hibernate配置文件中啟用查詢緩存    對于希望啟用查詢換的查詢語句,調用Query的setCacheable()方法

時間戳緩存區域  時間戳緩存區域存放了對于查詢結果相關的表進行插入,更新或刪除操作的時間戳。Hibernate通過時間戳緩存區域來判斷被緩存的查詢結果是否過期,其運行過程如下:    T1時刻執行查詢操作,把查詢結果存放在QueryCache區域,記錄該區域的時間戳為T1    T2時刻對查詢結果相關的表進行更新操作,Hibernate把T2時刻存放在UpdateTimestampCache區域    T3時刻執行查詢結果前,先比較QueryCache區域的時間戳和UpdateTimestampCache區域的時間戳,若T2>T1,那么久丟棄原先存放在QueryCache區域的查詢結果,更新到數據庫中查詢數據,再把結果存放到QueryCache區域;若T2<T1,直接從QueryCache中獲取查詢結果Query接口的iterate()方法  同list()一樣也能執行查詢操作  list()方法執行的SQL語句包含實體類對應的數據表的所有字段  iterate()方法執行的SQL語句中僅包含實體類對應的數據表的ID字段  當遍歷訪問結果集時,該方法先到Session緩存及二級緩存中查詢是否存在特定OID的對象,如果存在,就直接返回該對象,如果不存在,該對象就通過相應的SQL SELECT語句到數據庫中加載特定的實體對象大多數情況下,應考慮使用list()方法執行查詢操作。iterate()犯法僅在滿足一下條件的場合,可以稍微提高查詢性能:要查詢的數據表中包含大量的字段啟用了二級緩存,且二級緩存中可能已經包含了待查詢的對象

============================代碼說明==============================

hibernate.cfg.xml

 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6     <session-factory> 7         <!-- 配置連接數據庫的基本信息 --> 8         <property name="connection.username">scott</property> 9         <property name="connection.passWord">tiger</property>10         <property name="connection.driver_class">Oracle.jdbc.driver.OracleDriver</property>11         <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>12     13         <!-- 配置hibernate基本信息 -->14         <!-- hibernate所使用的數據庫方言 -->15         <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>16         17         <!-- 執行操作時是否在控制臺打印sql -->18         <property name="show_sql">true</property>19         20         <!-- 是否對SQL進行格式化 -->        21         <property name="format_sql">true</property>22         23         <!-- 指定自動生成數據表的策略 -->24         <property name="hbm2ddl.auto">update</property>25         26         <!-- 設置Hibernate 的事務的隔離級別 -->27         <property name="connection.isolation">2</property>28         29         <!-- 刪除對象后,使其OID置為null -->30         <property name="hibernate.use_identifier_rollback">true</property>31         32         <!-- 配置C3P0數據源 -->33         <!-- 34         <property name="hibernate.c3p0.max_size">10</property>35         <property name="hibernate.c3p0.min_size">5</property>36         <property name="c3p0.acquire_increment">2</property>37          38         <property name="c3p0.idle_test_period">2000</property>39         <property name="c3p0.timeout">2000</property>40         41         <property name="c3p0.max_statements">10</property>42          -->43          44         <!-- 設定JDBC的Statement 讀取數據的時候每次從數據庫中取出的數據條數 -->45         <property name="hibernate.jdbc.fetch_size">100</property>46          47         <!-- 設定對數據庫進行批量刪除、批量更新和批量插入的時候的批次的大小 -->48         <property name="hibernate.jdbc.batch_size">30</property>49         50         <!-- 啟用二級緩存 -->51         <property name="cache.use_second_level_cache">true</property>52         53         <!-- 配置使用的二級緩存的產品 -->54         <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>55         56         <!-- 配置啟用查詢緩存 -->57         <property name="cache.use_query_cache">true</property>58         59         <!-- 指定關聯的.hbm.xml 文件 -->60         <mapping resource="com/yl/hibernate/entities/Department.hbm.xml"/>61         <mapping resource="com/yl/hibernate/entities/Employee.hbm.xml"/>62         63         <class-cache usage="read-write" class="com.yl.hibernate.entities.Employee"/>64         65         <class-cache usage="read-only" class="com.yl.hibernate.entities.Department"/>66         <collection-cache usage="read-only" collection="com.yl.hibernate.entities.Department.emps"/>67 68     </session-factory>69 </hibernate-configuration>

ehcache.xml

<ehcache>    <!-- Sets the path to the directory where cache .data files are created.         If the path is a java System Property it is replaced by         its value in the running VM.         The following properties are translated:         user.home - User's home directory         user.dir - User's current working directory         java.io.tmpdir - Default temp file path -->    <!--         指定一個目錄,當EHCache 把數據寫到硬盤上時,將把數據寫到這個目錄下     -->    <!-- <diskStore path="java.io.tmpdir"/> -->    <diskStore path="D://tmpdir"/>    <!--Default Cache configuration. These will applied to caches programmatically created through        the CacheManager.        The following attributes are required for defaultCache:        maxInMemory       - Sets the maximum number of objects that will be created in memory        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element                            is never expired.        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used                            if the element is not eternal. Idle time is now - last accessed time        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used                            if the element is not eternal. TTL is now - creation time        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache                            has reached the maxInMemory limit.        -->    <!--         設置緩存的默認數據過期策略     -->    <defaultCache        maxElementsInMemory="10000"        eternal="false"        timeToIdleSeconds="120"        timeToLiveSeconds="120"        overflowToDisk="true"        />    <!--Predefined caches.  Add your cache configuration settings here.        If you do not have a configuration for your cache a WARNING will be issued when the        CacheManager starts        The following attributes are required for defaultCache:        name              - Sets the name of the cache. This is used to identify the cache. It must be unique.        maxInMemory       - Sets the maximum number of objects that will be created in memory        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element                            is never expired.        timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used                            if the element is not eternal. Idle time is now - last accessed time        timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used                            if the element is not eternal. TTL is now - creation time        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache                            has reached the maxInMemory limit.        -->    <!-- Sample cache named sampleCache1        This cache contains a maximum in memory of 10000 elements, and will expire        an element if it is idle for more than 5 minutes and lives for more than        10 minutes.        If there are more than 10000 elements it will overflow to the        disk cache, which in this configuration will go to wherever java.io.tmp is        defined on your system. On a standard linux system this will be /tmp"        -->    <!--         設定具體的命名緩存的數據過期策略。每個命名緩存代表一個緩存區域        緩存區域(region):一個具有名稱的緩存塊,可以給每一個緩存塊設置不同的緩存策略。        如果沒有設置任何的緩存區域,則所有被緩存的對象,都將使用默認的緩存策略。即:<defaultCache.../>                Hibernate在不同的緩存區域保存不同的類/集合            對于類而言,區域的名稱是類名。如:com.yl.domain.Customer            對于集合而言,區域的名稱是類名加屬性名。如:com.yl.domain.Customer.orders     -->     <!--          name:設置緩存的名字,它的取值為類的全限定名或類的集合的名字        maxInMemory:設置基于內存的緩存中可存放的對象最大數目        eternal:設置對象是否為永久的,true表示永不過期,此時將忽略timeToIdleSeconds和timeToLiveSeconds屬性;默認值是false        timeToIdleSeconds:設置對象空閑最長時間,以秒為單位,超過這個時間,對象過期,當對象過期時,EHCache會把它從緩存中清除。如果此值為0,表示對象可以無限期地處于空閑狀態        timeToLiveSeconds:設置對象生存最長時間,超過這個時間,對象過期。如果此值為0,表示對象可以無限期地存在于緩存中。該屬性值必須大于或等于timeToIdleSeconds屬性值        overflowToDisk:設置基于內在的緩存中的對象數目達到上線后,是否把溢出的對象寫到基于硬盤的緩存中      -->    <cache name="com.yl.hibernate.entities.Employee"        maxElementsInMemory="1"        eternal="false"        timeToIdleSeconds="300"        timeToLiveSeconds="600"        overflowToDisk="true"        />    <!-- Sample cache named sampleCache2        This cache contains 1000 elements. Elements will always be held in memory.        They are not expired. -->    <cache name="com.yl.hibernate.entities.Department.emps"        maxElementsInMemory="1000"        eternal="true"        timeToIdleSeconds="0"        timeToLiveSeconds="0"        overflowToDisk="false"        /> -->    <!-- Place configuration for your caches following --></ehcache>

測試類:

  1 package com.yl.hibernate.test;  2   3   4 import java.util.ArrayList;  5 import java.util.Arrays;  6 import java.util.Iterator;  7 import java.util.LinkedHashSet;  8 import java.util.List;  9 import java.util.Set; 10  11 import oracle.net.aso.e; 12  13 import org.hibernate.Criteria; 14 import org.hibernate.Query; 15 import org.hibernate.Session; 16 import org.hibernate.SessionFactory; 17 import org.hibernate.Transaction; 18 import org.hibernate.cfg.Configuration; 19 import org.hibernate.criterion.Conjunction; 20 import org.hibernate.criterion.Disjunction; 21 import org.hibernate.criterion.MatchMode; 22 import org.hibernate.criterion.Order; 23 import org.hibernate.criterion.Projection; 24 import org.hibernate.criterion.Projections; 25 import org.hibernate.criterion.Restrictions; 26 import org.hibernate.service.ServiceRegistry; 27 import org.hibernate.service.ServiceRegistryBuilder; 28 import org.junit.After; 29 import org.junit.Before; 30 import org.junit.Test; 31  32 import com.yl.hibernate.entities.Department; 33 import com.yl.hibernate.entities.Employee; 34  35 public class HibernateTest { 36  37     private SessionFactory sessionFactory; 38     private Session session; 39     private Transaction transaction; 40      41     @Before 42     public void init() { 43         Configuration configuration = new Configuration().configure(); 44         ServiceRegistry serviceRegistry =  45                 new ServiceRegistryBuilder().applySettings(configuration.getProperties()) 46                                             .buildServiceRegistry(); 47  48         sessionFactory = configuration.buildSessionFactory(serviceRegistry); 49          50         session = sessionFactory.openSession(); 51  52         transaction = session.beginTransaction(); 53     } 54     @After 55     public void destory() { 56         transaction.commit(); 57          58         session.close(); 59          60         sessionFactory.close(); 61     } 62  63      64     @Test 65     public void testHibernateSecondLevelCache() { 66         Employee employee = (Employee) session.get(Employee.class, 7369); 67         System.out.println(employee.getName()); 68          69         transaction.commit(); 70         session.close(); 71          72         session = sessionFactory.openSession(); 73         transaction = session.beginTransaction(); 74          75         Employee employee2 = (Employee) session.get(Employee.class, 7369); 76         System.out.println(employee2.getName()); 77          78     } 79      80     @Test 81     public void testCollectionSecondLevelCache() { 82         Department dept = (Department) session.get(Department.class, 20); 83         System.out.println(dept.getName()); 84         System.out.println(dept.getEmps().size()); 85          86         transaction.commit(); 87         session.close(); 88          89         session = sessionFactory.openSession(); 90         transaction = session.beginTransaction(); 91          92         Department dept2 = (Department) session.get(Department.class, 20); 93         System.out.println(dept2.getName()); 94         System.out.println(dept2.getEmps().size()); 95     } 96      97     /** 98      * 查詢緩存依賴于二級緩存 99      */100     @Test101     public void TestQueryCache() {102         Query query = session.createQuery("FROM Employee");103         query.setCacheable(true);104         105         List<Employee> emps = query.list();106         System.out.println(emps.size());107         108         emps = query.list();109         System.out.println(emps.size());110         111         Criteria criteria = session.createCriteria(Employee.class);112         criteria.setCacheable(true);113     }114     115     @Test116     public void testUpdateTimestampCache() {117         Query query = session.createQuery("FROM Employee");118         query.setCacheable(true);119         120         List<Employee> emps = query.list();121         System.out.println(emps.size());122         123         Employee employee = (Employee) session.get(Employee.class, 7839);124         employee.setSalary(15000F);125         126         emps = query.list();127         System.out.println(emps.size());128     }129     130     @Test131     public void testQueryIterate() {132         Department dept = (Department) session.get(Department.class, 20);133         System.out.println(dept.getName());134         System.out.println(dept.getEmps().size());135         136         Query query = session.createQuery("FROM Employee e WHERE e.dept.id = 20");137         /*List<Employee> emps = query.list();138         System.out.println(emps.size());*/139         140         Iterator<Employee> empIt = query.iterate();141         while (empIt.hasNext()) {142             System.out.println(empIt.next().getName());143         }144         145     }146     147     148     149 }


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 柏乡县| 利津县| 盘山县| 德惠市| 泰州市| 宜君县| 虞城县| 台中市| 武清区| 泗阳县| 怀仁县| 彭山县| 鄂托克旗| 通州市| 高邮市| 山西省| 辽阳市| 洱源县| 宁都县| 灵武市| 温州市| 濮阳县| 静乐县| 鹤岗市| 仙桃市| 大兴区| 阿瓦提县| 兴和县| 灯塔市| 尼勒克县| 且末县| 沧源| 东乌| 宿州市| 东海县| 京山县| 丹棱县| 忻城县| 尼玛县| 二手房| 平陆县|