查询缓存中的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所要获取的对象在前面的查询中已经获得了,并进行了缓存,因此没有再次执行查询语句。