精通Hibernate管理緩存
無(wú)論何時(shí),我們?cè)诠芾鞨ibernate緩存(Managing the caches)時(shí),當(dāng)你給save()、update()或saveOrUpdate()方法傳遞一個(gè)對(duì)象時(shí),或使用load()、 get()、list()、iterate() 或scroll()方法獲得一個(gè)對(duì)象時(shí), 該對(duì)象都將被加入到Session的內(nèi)部緩存中。
當(dāng)隨后flush()方法被調(diào)用時(shí),對(duì)象的狀態(tài)會(huì)和數(shù)據(jù)庫(kù)取得同步。 如果你不希望此同步操作發(fā)生,或者你正處理大量對(duì)象、需要對(duì)有效管理內(nèi)存時(shí),你可以調(diào)用evict() 方法,從一級(jí)緩存中去掉這些對(duì)象及其集合。
- ScrollableResult cats = sess.createQuery("from Cat as cat").scroll(); //a huge result set
- while ( cats.next() ) {
- Cat cat = (Cat) cats.get(0);
- doSomethingWithACat(cat);
- sess.evict(cat);
- }
Session還提供了一個(gè)contains()方法,用來(lái)判斷某個(gè)實(shí)例是否處于當(dāng)前session的緩存中。
如若要把所有的對(duì)象從session緩存中徹底清除,則需要調(diào)用Session.clear()。
對(duì)于二級(jí)緩存來(lái)說(shuō),在SessionFactory中定義了許多方法, 清除緩存中實(shí)例、整個(gè)類(lèi)、集合實(shí)例或者整個(gè)集合。
- sessionFactory.evict(Cat.class, catId); //evict a particular Cat
- sessionFactory.evict(Cat.class); //evict all Cats
- sessionFactory.evictCollection("Cat.kittens", catId); //evict a particular collection of kittens
- sessionFactory.evictCollection("Cat.kittens"); //evict all kitten collections
CacheMode參數(shù)用于控制具體的Session如何與二級(jí)緩存進(jìn)行交互。
CacheMode.NORMAL - 從二級(jí)緩存中讀、寫(xiě)數(shù)據(jù)。
CacheMode.GET - 從二級(jí)緩存中讀取數(shù)據(jù),僅在數(shù)據(jù)更新時(shí)對(duì)二級(jí)緩存寫(xiě)數(shù)據(jù)。
CacheMode.PUT - 僅向二級(jí)緩存寫(xiě)數(shù)據(jù),但不從二級(jí)緩存中讀數(shù)據(jù)。
CacheMode.REFRESH - 僅向二級(jí)緩存寫(xiě)數(shù)據(jù),但不從二級(jí)緩存中讀數(shù)據(jù)。通過(guò) hibernate.cache.use_minimal_puts的設(shè)置,強(qiáng)制二級(jí)緩存從數(shù)據(jù)庫(kù)中讀取數(shù)據(jù),刷新Hibernate緩存內(nèi)容。
如若需要查看二級(jí)緩存或查詢(xún)Hibernate緩存區(qū)域的內(nèi)容,你可以使用統(tǒng)計(jì)(Statistics) API。
- Map cacheEntries = sessionFactory.getStatistics()
- .getSecondLevelCacheStatistics(regionName)
- .getEntries();
此時(shí),你必須手工打開(kāi)統(tǒng)計(jì)選項(xiàng)。可選的,你可以讓Hibernate更人工可讀的方式維護(hù)Hibernate緩存內(nèi)容。
- hibernate.generate_statistics true
- hibernate.cache.use_structured_entries true
【編輯推薦】