hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存

本篇文章為大家展示了hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過(guò)這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計(jì)、做網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)景縣,10年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專(zhuān)業(yè),歡迎來(lái)電咨詢(xún)建站服務(wù):18982081108

Hibernate的二級(jí)緩存

一、緩存概述

緩存(Cache): 計(jì)算機(jī)領(lǐng)域非常通用的概念。它介于應(yīng)用程序和永久性數(shù)據(jù)存儲(chǔ)源(如硬盤(pán)上的文件或者數(shù)據(jù)庫(kù))之間,其作用是降低應(yīng)用程序直接讀寫(xiě)永久性數(shù)據(jù)存儲(chǔ)源的頻率,從而提高應(yīng)用的運(yùn)行性能。緩存中的數(shù)據(jù)是數(shù)據(jù)存儲(chǔ)源中數(shù)據(jù)的拷貝。緩存的物理介質(zhì)通常是內(nèi)存

hibernate中提供了兩個(gè)級(jí)別的緩存

第一級(jí)別的緩存是 Session 級(jí)別的緩存,它是屬于事務(wù)范圍的緩存。這一級(jí)別的緩存由 hibernate 管理的,一般情況下無(wú)需進(jìn)行干預(yù)

第二級(jí)別的緩存是 SessionFactory 級(jí)別的緩存,它是屬于進(jìn)程范圍的緩存

Hibernate 的緩存可以分為兩類(lèi):

內(nèi)置緩存: Hibernate 自帶的, 不可卸載. 通常在 Hibernate 的初始化階段, Hibernate 會(huì)把映射元數(shù)據(jù)和預(yù)定義的 SQL 語(yǔ)句放到 SessionFactory 的緩存中, 映射元數(shù)據(jù)是映射文件中數(shù)據(jù)的復(fù)制, 而預(yù)定義 SQL 語(yǔ)句時(shí) Hibernate 根據(jù)映射元數(shù)據(jù)推到出來(lái)的. 該內(nèi)置緩存是只讀的.

外置緩存(二級(jí)緩存): 一個(gè)可配置的緩存插件. 在默認(rèn)情況下, SessionFactory 不會(huì)啟用這個(gè)緩存插件. 外置緩存中的數(shù)據(jù)是數(shù)據(jù)庫(kù)數(shù)據(jù)的復(fù)制, 外置緩存的物理介質(zhì)可以是內(nèi)存或硬盤(pán)

hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存

二、理解二級(jí)緩存的并發(fā)訪(fǎng)問(wèn)策略

hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存

三、配置進(jìn)程范圍內(nèi)的二級(jí)緩存(配置ehcache緩存)

1 拷貝ehcache-1.5.0.jar到當(dāng)前工程的lib目錄下

依賴(lài) backport-util-concurrent 和 commons-logging

2 開(kāi)啟二級(jí)緩存

<property name="hibernate.cache.use_second_level_cache">true</property>

3 要指定緩存的供應(yīng)商

 <property name="hibernate.cache.provider_class">
    org.hibernate.cache.EhCacheProvider</property>

4 指定使用二級(jí)緩存的類(lèi)

方法一 在使用類(lèi)的*.hbm.xml配置

選擇需要使用二級(jí)緩存的持久化類(lèi), 設(shè)置它的二級(jí)緩存的并發(fā)訪(fǎng)問(wèn)策略, <class> 元素的 cache 子元素表明 Hibernate 會(huì)緩存對(duì)象的簡(jiǎn)單屬性, 但不會(huì)緩存集合屬性, 若希望緩存集合屬性中的元素, 必須在 <set> 元素中加入 <cache> 子元素

方法二  在hibernate.cfg.xml文件中配置(建議)

  <!-- 指定使用二級(jí)緩存的類(lèi) 放在maping下面 -->
  <!-- 配置類(lèi)級(jí)別的二級(jí)緩存 -->
  <class-cache class="com.sihai.c3p0.Customer" usage="read-write"/>
  <class-cache class="com.sihai.c3p0.Order" usage="read-write"/>
 
  <!-- 配置集合級(jí)別的二級(jí)緩存 -->
  <collection-cache collection="com.sihai.c3p0.Customer.orders" 
         usage="read-write"/>

5  配置ehcache默認(rèn)的配置文件ehcache.xml(名字固定)(放在類(lèi)路徑下)

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd"> 
 
 <diskStore path="c:/ehcache"/> 
 <defaultCache 
   maxElementsInMemory="5" 
   eternal="false" 
   timeToIdleSeconds="120" 
   timeToLiveSeconds="120" 
   overflowToDisk="true" 
   maxElementsOnDisk="10000000" 
   diskPersistent="false" 
   diskExpiryThreadIntervalSeconds="120" 
   memoryStoreEvictionPolicy="LRU" 
   /> 
</ehcache> 

四、 測(cè)試

package com.sihai.hibernate3.test; 
 
import java.util.Iterator; 
import java.util.List; 
 
import org.hibernate.Query; 
import org.hibernate.Session; 
import org.hibernate.Transaction; 
import org.junit.Test; 
 
import com.sihai.hibernate3.demo1.Customer; 
import com.sihai.hibernate3.demo1.Order; 
import com.sihai.utils.HibernateUtils; 
 
public class HibernateTest6 { 
  
 @Test 
 // 查詢(xún)緩存的測(cè)試 
 public void demo9(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Query query = session.createQuery("select c.cname from Customer c"); 
  // 使用查詢(xún)緩存: 
  query.setCacheable(true); 
  query.list(); 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  query = session.createQuery("select c.cname from Customer c"); 
  query.setCacheable(true); 
  query.list(); 
   
  tx.commit(); 
 } 
  
 @SuppressWarnings("unused") 
 @Test 
 // 更新時(shí)間戳 
 public void demo8(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Customer customer = (Customer) session.get(Customer.class, 2); 
  session.createQuery("update Customer set cname = '奶茶' where cid = 2").executeUpdate(); 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  Customer customer2 = (Customer) session.get(Customer.class, 2); 
   
  tx.commit(); 
 } 
  
 @SuppressWarnings("all") 
 @Test 
 // 將內(nèi)存中的數(shù)據(jù)寫(xiě)到硬盤(pán) 
 public void demo7(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  List<Order> list = session.createQuery("from Order").list(); 
   
  tx.commit(); 
 } 
  
 @Test 
 // 一級(jí)緩存的更新會(huì)同步到二級(jí)緩存: 
 public void demo6(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Customer customer = (Customer) session.get(Customer.class, 1); 
  customer.setCname("芙蓉"); 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  Customer customer2 = (Customer) session.get(Customer.class, 1); 
   
  tx.commit(); 
 } 
  
 @SuppressWarnings("unchecked") 
 @Test 
 // iterate()方法可以查詢(xún)所有信息. 
 // iterate方法會(huì)發(fā)送N+1條SQL查詢(xún).但是會(huì)使用二級(jí)緩存的數(shù)據(jù) 
 public void demo5(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  // N+1條SQL去查詢(xún). 
  Iterator<Customer> iterator = session.createQuery("from Customer").iterate(); 
  while(iterator.hasNext()){ 
   Customer customer = iterator.next(); 
   System.out.println(customer); 
  } 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  iterator = session.createQuery("from Customer").iterate(); 
  while(iterator.hasNext()){ 
   Customer customer = iterator.next(); 
   System.out.println(customer); 
  } 
   
  tx.commit(); 
 } 
  
 @SuppressWarnings("unchecked") 
 @Test 
 // 查詢(xún)所有.Query接口的list()方法. 
 // list()方法會(huì)向二級(jí)緩存中放數(shù)據(jù),但是不會(huì)使用二級(jí)緩存中的數(shù)據(jù). 
 public void demo4(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  // 查詢(xún)所有客戶(hù): 
  // list方法會(huì)向二級(jí)緩存中放入數(shù)據(jù)的. 
  List<Customer> list = session.createQuery("from Customer").list(); 
  for (Customer customer : list) { 
   System.out.println(customer.getCname()); 
  } 
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  // Customer customer = (Customer) session.get(Customer.class, 1);// 沒(méi)有發(fā)生SQL ,從二級(jí)緩存獲取的數(shù)據(jù). 
  // list()方法沒(méi)有使用二級(jí)緩存的數(shù)據(jù). 
  list = session.createQuery("from Customer").list(); 
  for (Customer customer : list) { 
   System.out.println(customer.getCname()); 
  } 
   
  tx.commit(); 
 } 
  
 @Test 
 // 二級(jí)緩存的集合緩沖區(qū)特點(diǎn): 
 public void demo3(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Customer customer = (Customer) session.get(Customer.class, 1); 
  // 查詢(xún)客戶(hù)的訂單. 
  System.out.println("訂單的數(shù)量:"+customer.getOrders().size()); 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  Customer customer2 = (Customer) session.get(Customer.class, 1); 
  // 查詢(xún)客戶(hù)的訂單. 
  System.out.println("訂單的數(shù)量:"+customer2.getOrders().size()); 
   
  tx.commit(); 
 } 
  
 @SuppressWarnings("unused") 
 @Test 
 // 配置二級(jí)緩存的情況 
 public void demo2(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Customer customer1 = (Customer) session.get(Customer.class, 1);// 發(fā)送SQL. 
   
  Customer customer2 = (Customer) session.get(Customer.class, 1);// 不發(fā)送SQL. 
   
  System.out.println(customer1 == customer2); 
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  Customer customer3 = (Customer) session.get(Customer.class, 1);// 不發(fā)送SQL. 
  Customer customer4 = (Customer) session.get(Customer.class, 1);// 不發(fā)送SQL. 
   
  System.out.println(customer3 == customer4); 
   
  tx.commit(); 
 } 
  
  
 @SuppressWarnings("unused") 
 @Test 
 // 沒(méi)有配置二級(jí)緩存的情況 
 public void demo1(){ 
  Session session = HibernateUtils.getCurrentSession(); 
  Transaction tx = session.beginTransaction(); 
   
  Customer customer1 = (Customer) session.get(Customer.class, 1);// 發(fā)送SQL. 
   
  Customer customer2 = (Customer) session.get(Customer.class, 1);// 不發(fā)送SQL. 
   
   
   
  tx.commit(); 
   
  session = HibernateUtils.getCurrentSession(); 
  tx = session.beginTransaction(); 
   
  Customer customer3 = (Customer) session.get(Customer.class, 1);// 發(fā)送SQL. 
   
   
  tx.commit(); 
 } 
} 

上述內(nèi)容就是hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

新聞名稱(chēng):hibernate在java中使用如何實(shí)現(xiàn)二級(jí)緩存
文章位置:http://muchs.cn/article46/pihhhg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站設(shè)計(jì)、營(yíng)銷(xiāo)型網(wǎng)站建設(shè)、云服務(wù)器用戶(hù)體驗(yàn)、定制網(wǎng)站、網(wǎng)站營(yíng)銷(xiāo)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都seo排名網(wǎng)站優(yōu)化