hibernate教程--二级缓存详解
?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 的緩存可以分為兩類:
內(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)
二、理解二級(jí)緩存的并發(fā)訪問(wèn)策略
三、配置進(jìn)程范圍內(nèi)的二級(jí)緩存(配置ehcache緩存)
1 拷貝ehcache-1.5.0.jar到當(dāng)前工程的lib目錄下
依賴 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í)緩存的類
??? 方法一 在使用類的*.hbm.xml配置
選擇需要使用二級(jí)緩存的持久化類, 設(shè)置它的二級(jí)緩存的并發(fā)訪問(wèn)策略, <class> 元素的 cache 子元素表明 Hibernate 會(huì)緩存對(duì)象的簡(jiǎn)單屬性, 但不會(huì)緩存集合屬性, 若希望緩存集合屬性中的元素, 必須在 <set> 元素中加入 <cache> 子元素
??? 方法二? 在hibernate.cfg.xml文件中配置(建議)
????? <!-- 指定使用二級(jí)緩存的類 放在maping下面 -->
????? <!-- 配置類級(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(名字固定)(放在類路徑下)
四、 測(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// 查詢緩存的測(cè)試public void demo9(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();Query query = session.createQuery("select c.cname from Customer c");// 使用查詢緩存: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()方法可以查詢所有信息.// iterate方法會(huì)發(fā)送N+1條SQL查詢.但是會(huì)使用二級(jí)緩存的數(shù)據(jù)public void demo5(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();// N+1條SQL去查詢.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// 查詢所有.Query接口的list()方法.// list()方法會(huì)向二級(jí)緩存中放數(shù)據(jù),但是不會(huì)使用二級(jí)緩存中的數(shù)據(jù).public void demo4(){Session session = HibernateUtils.getCurrentSession();Transaction tx = session.beginTransaction();// 查詢所有客戶:// 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);// 查詢客戶的訂單.System.out.println("訂單的數(shù)量:"+customer.getOrders().size());tx.commit();session = HibernateUtils.getCurrentSession();tx = session.beginTransaction();Customer customer2 = (Customer) session.get(Customer.class, 1);// 查詢客戶的訂單.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();} }總結(jié)
以上是生活随笔為你收集整理的hibernate教程--二级缓存详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: hibernate教程--抓取策略详解
- 下一篇: spring教程--AOP详解