這篇主要講 hibernate緩存
1.緩存的作用是為了提高效率
2.Hibernate的開發效率比較高,但是執行效率相對較低。
3.Hibernate提供了緩存來提高效率。hibernate緩存分為:一級緩存,二級緩存,查詢緩存。
4.一級緩存又稱為 session緩存,是線程級別的緩存。
get 和 load 方法查詢數據 首先檢查session緩存中是否有該數據,如果有,從緩存中直接獲取數據,如果沒有則查詢數據庫,並且寫入緩存。
@Test public void testGet(){ Session session = HibernateUtil.getSession(); Book b=(Book)session.get(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); b=(Book)session.get(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); } @Test public void testLoad(){ Session session = HibernateUtil.getSession(); Book b=(Book)session.load(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); b=(Book)session.load(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); }
在這兩個方法中,第一次會執行sql語句查詢,第二次則不會生成sql語句查詢,直接從緩存中取數據了。
list方法查詢數據,不會查看session緩存,直接從數據庫中獲取。list 查詢數據后,會將數據寫入 Session緩存。
@Test public void testIterate(){ Session session = HibernateUtil.getSession(); Iterator<Book> iter = session.createQuery("from Book").iterate(); while(iter.hasNext()){ Book b = iter.next(); System.out.println(b.getName()+"---"+b.getAuthor()); } System.out.println("=============================="); iter = session.createQuery("from Book").iterate(); while(iter.hasNext()){ Book b = iter.next(); System.out.println(b.getName()+"---"+b.getAuthor()); } }
Session的管理:clear 清空緩存中數據,close 關閉, evict 清除指定對象
5.二級緩存又稱為 SessionFactory緩存,是進程級別的緩存。聲明周期很長。一般有緩存數據清理算法來清除緩存中的數據。
LRU ---最近最少使用,FIFO 、LFU 、LRU ;
6.二級緩存的實現步驟
a). 導入 jar 包 --lib\optional\ehcache 下的所有包
ehcache-core-2.4.3.jar
hibernate-ehcache-4.3.10.Final.jar
slf4j-api-1.6.1.jar
b). 導入ehcache.xml 文件 project\etc 下的ehcache.xml 放入 src 下
<ehcache> <diskStore path="java.io.tmpdir"/> <!-- maxElementsInMemory 最大存放元素個數 eternal 是否永久存儲 timeToIdleSeconds 空閑秒數 timeToLiveSeconds 存活時間數 overflowToDisk 溢出是否寫入磁盤 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> </ehcache>
c). 在映射文件 添加 cache 標簽,指明使用二級緩存的方式
<hibernate-mapping package="cn.sxt.pojo"> <class name="Book" table="t_book"> <cache usage="read-only"/> <id name="id"> <generator class="native"></generator> </id> <property name="name"/> <property name="author"/> <property name="price"/> <property name="pubDate"/> <!-- 多對一的關聯關系設置 column指定外鍵的名稱 --> <many-to-one name="category" column="cid" fetch="join"/> </class> </hibernate-mapping>
d). 在 hibernate.cfg.xml 的通用配置中,開啟二級緩存和 3.x 不一致
<!-- 開啟二級緩存 -->
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
e)測試 –如果session被關閉后,數據只查詢一次,那么二級緩存開啟成功
@Test public void testGet(){ Session session = HibernateUtil.getSession(); Book b=(Book)session.get(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); System.out.println("========================="); HibernateUtil.close(); session = HibernateUtil.getSession(); b=(Book)session.get(Book.class, 1); System.out.println(b.getName()+"---"+b.getAuthor()); }
7. 查詢緩存,查詢緩存是在二級緩存的基礎上的。也就是首先要先開啟二級緩存,查詢緩存的配置,在hibernate.cfg.xml中添加通用配置
<!-- 開啟查詢緩存 -->
<property name="cache.use_query_cache">true</property>
在查詢時需要指明使用查詢緩存: 以下代碼如果只查詢一次,那么查詢緩存設置成功
@Test public void testList(){ Session session = HibernateUtil.getSession(); session.createQuery("from Book") .setCacheable(true)//設置使用查詢緩存 .list(); System.out.println("================="); session.createQuery("from Book") .setCacheable(true)//設置使用查詢緩存 .list(); System.out.println("===================="); session.load(Book.class, 1); }