您好,登錄后才能下訂單哦!
本篇文章為大家展示了hibernate在java中使用如何實現二級緩存,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。
Hibernate的二級緩存
一、緩存概述
緩存(Cache): 計算機領域非常通用的概念。它介于應用程序和永久性數據存儲源(如硬盤上的文件或者數據庫)之間,其作用是降低應用程序直接讀寫永久性數據存儲源的頻率,從而提高應用的運行性能。緩存中的數據是數據存儲源中數據的拷貝。緩存的物理介質通常是內存
hibernate中提供了兩個級別的緩存
第一級別的緩存是 Session 級別的緩存,它是屬于事務范圍的緩存。這一級別的緩存由 hibernate 管理的,一般情況下無需進行干預
第二級別的緩存是 SessionFactory 級別的緩存,它是屬于進程范圍的緩存
Hibernate 的緩存可以分為兩類:
內置緩存: Hibernate 自帶的, 不可卸載. 通常在 Hibernate 的初始化階段, Hibernate 會把映射元數據和預定義的 SQL 語句放到 SessionFactory 的緩存中, 映射元數據是映射文件中數據的復制, 而預定義 SQL 語句時 Hibernate 根據映射元數據推到出來的. 該內置緩存是只讀的.
外置緩存(二級緩存): 一個可配置的緩存插件. 在默認情況下, SessionFactory 不會啟用這個緩存插件. 外置緩存中的數據是數據庫數據的復制, 外置緩存的物理介質可以是內存或硬盤
二、理解二級緩存的并發訪問策略
三、配置進程范圍內的二級緩存(配置ehcache緩存)
1 拷貝ehcache-1.5.0.jar到當前工程的lib目錄下
依賴 backport-util-concurrent 和 commons-logging
2 開啟二級緩存
<property name="hibernate.cache.use_second_level_cache">true</property>
3 要指定緩存的供應商
<property name="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</property>
4 指定使用二級緩存的類
方法一 在使用類的*.hbm.xml配置
選擇需要使用二級緩存的持久化類, 設置它的二級緩存的并發訪問策略, <class> 元素的 cache 子元素表明 Hibernate 會緩存對象的簡單屬性, 但不會緩存集合屬性, 若希望緩存集合屬性中的元素, 必須在 <set> 元素中加入 <cache> 子元素
方法二 在hibernate.cfg.xml文件中配置(建議)
<!-- 指定使用二級緩存的類 放在maping下面 --> <!-- 配置類級別的二級緩存 --> <class-cache class="com.sihai.c3p0.Customer" usage="read-write"/> <class-cache class="com.sihai.c3p0.Order" usage="read-write"/> <!-- 配置集合級別的二級緩存 --> <collection-cache collection="com.sihai.c3p0.Customer.orders" usage="read-write"/>
5 配置ehcache默認的配置文件ehcache.xml(名字固定)(放在類路徑下)
<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>
四、 測試
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 // 查詢緩存的測試 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 // 更新時間戳 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 // 將內存中的數據寫到硬盤 public void demo7(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); List<Order> list = session.createQuery("from Order").list(); tx.commit(); } @Test // 一級緩存的更新會同步到二級緩存: 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方法會發送N+1條SQL查詢.但是會使用二級緩存的數據 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()方法會向二級緩存中放數據,但是不會使用二級緩存中的數據. public void demo4(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); // 查詢所有客戶: // list方法會向二級緩存中放入數據的. 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);// 沒有發生SQL ,從二級緩存獲取的數據. // list()方法沒有使用二級緩存的數據. list = session.createQuery("from Customer").list(); for (Customer customer : list) { System.out.println(customer.getCname()); } tx.commit(); } @Test // 二級緩存的集合緩沖區特點: public void demo3(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer = (Customer) session.get(Customer.class, 1); // 查詢客戶的訂單. System.out.println("訂單的數量:"+customer.getOrders().size()); tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer2 = (Customer) session.get(Customer.class, 1); // 查詢客戶的訂單. System.out.println("訂單的數量:"+customer2.getOrders().size()); tx.commit(); } @SuppressWarnings("unused") @Test // 配置二級緩存的情況 public void demo2(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1);// 發送SQL. Customer customer2 = (Customer) session.get(Customer.class, 1);// 不發送SQL. System.out.println(customer1 == customer2); tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer3 = (Customer) session.get(Customer.class, 1);// 不發送SQL. Customer customer4 = (Customer) session.get(Customer.class, 1);// 不發送SQL. System.out.println(customer3 == customer4); tx.commit(); } @SuppressWarnings("unused") @Test // 沒有配置二級緩存的情況 public void demo1(){ Session session = HibernateUtils.getCurrentSession(); Transaction tx = session.beginTransaction(); Customer customer1 = (Customer) session.get(Customer.class, 1);// 發送SQL. Customer customer2 = (Customer) session.get(Customer.class, 1);// 不發送SQL. tx.commit(); session = HibernateUtils.getCurrentSession(); tx = session.beginTransaction(); Customer customer3 = (Customer) session.get(Customer.class, 1);// 發送SQL. tx.commit(); } }
上述內容就是hibernate在java中使用如何實現二級緩存,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。