查詢緩存中的key是根據查詢的語句、查詢的條件、查詢的參數和查詢的頁數等信息組成的。而數據的存儲則會使用兩種方式,使用SELECT語句只查詢實體 對象的某些列或者某些實體對象列的組合時,會直接緩存整個結果集。而對於查詢結果爲某個實體對象集合的狀況則只會緩存實體對象的ID值,以達到緩存空間可 以共用,節省空間的目的。java
在使用查詢緩存時,除了須要設置hibernate.cache.provider_class參數來啓動二級緩存外,還須要經過hibernate.cache.use_query_cache參數來啓動對查詢緩存的支持。緩存
另外須要注意的是,查詢緩存是在執行查詢語句的時候指定緩存的方式以及是否須要對查詢的結果進行緩存。session
下面就來了解一下查詢緩存的使用方法及做用。多線程
修改Hibernate配置文件ide
首先須要修改Hibernate的配置文件,增長hibernate.cache.use_query_cache參數的配置。配置方法以下:測試
<property name="hibernate.cache.use_query_cache">true</property>ui
Hibernate配置文件的詳細內容請參考配套光盤中的hibernate\src\cn\hxex\ hibernate\cache\hibernate.cfg.xml文件。spa
編寫主測試程序hibernate
因爲這是在前面二級緩存例子的基礎上來開發的,因此,對於EHCache的配置以及視圖對象的開發和映射文件的配置工做就都不須要再從新進行了。下面就來看一下主測試程序的實現方法,如清單14.11所示。線程
清單14.11 主程序的實現
import java.util.Iterator; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class QueryCache extends Thread { public static final SessionFactory sessionFactory; static { try { // Create the SessionFactory from hibernate.cfg.xml sessionFactory = new Configuration().configure() .buildSessionFactory(); } catch (Throwable ex) { // Make sure you log the exception, as it might be swallowed System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } public void run() { SessionFactory sf = QueryCache.sessionFactory; Session session = sf.getCurrentSession(); session.beginTransaction(); Query query = session.createQuery("from User"); Iterator it = query.setCacheable(true).list().iterator(); while (it.hasNext()) { System.out.println(it.next()); } // User user = (User)session.get( User.class, "1" ); // System.out.println(user); session.getTransaction().commit(); } public static void main(String[] args) { QueryCache main1 = new QueryCache(); main1.start(); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } QueryCache main2 = new QueryCache(); main2.start(); } }
主程序在實現的時候採用了多線程的方式來運行。首先將「from User」查詢結果進行緩存,而後再經過ID取得對象來檢查是否對對象進行了緩存。另外,多個線程的執行能夠看出對於進行了緩存的查詢是不會執行第二次的。
運行測試主程序
接着就來運行測試主程序,其輸出結果應該以下所示:
Hibernate: select user0_.userId as userId0_, user0_.name as name0_, user0_.age as age0_ from USERINFO user0_
ID: 1
Namge: galaxy
Age: 32
ID: 1
Namge: galaxy
Age: 32
ID: 1
Namge: galaxy
Age: 32
ID: 1
Namge: galaxy
Age: 32
經過上面的執行結果能夠看到,在兩個線程執行中,只執行了一個SQL查詢語句。這是由於根據ID所要獲取的對象在前面的查詢中已經獲得了,並進行了緩存,因此沒有再次執行查詢語句。