对于一个应用来说,最多的操作是查询,而并非是写入和更改,如果能将查询缓存起来,那么能够有效提升效率。
Hibernate的查询缓存是基于二级缓存的,所以,如果想使用查询缓存,必须先开启二级缓存。
1.开启查询缓存
在hibernate.cfg.xml中配置
<property name="cache.use_query_cache">true</property>
2.测试
package com.wicresoft.test;
import static org.junit.Assert.*;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import com.wicresoft.model.Teacher;
public class TestQueryCache {
@Test
public void test() {
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sf = cfg.buildSessionFactory();
Session session = sf.openSession();
session.beginTransaction();
session.getTransaction().commit();
List<Teacher> teachers1 = (List<Teacher>)session.createQuery("from Teacher ")
.setCacheable(true)
.list();
List<Teacher> teachers2 = (List<Teacher>)session.createQuery("from Teacher ")
.setCacheable(true)
.list();
session.close();
Session session1 = sf.openSession();
session1.beginTransaction();
session1.getTransaction().commit();
List<Teacher> teachers3 = (List<Teacher>)session1.createQuery("from Teacher ")
.setCacheable(true)
.list();
session1.close();
sf.close();
}
}
这里有两个session,执行了相同的查询操作,如果查询缓存启用,那么,只会输出一个sql
结果如下:
Hibernate:
select
teacher0_.id as id1_0_,
teacher0_.name as name2_0_,
teacher0_.title as title3_0_
from
Teacher teacher0_
说明查询缓存已经启用!
关于查询缓存的算法
缓存算法有:
LRU(Least Recently Used):这种算法是在每个对象中维护一个访问的时间变量,每次访问后,时间都会更新,当新的对象需要存放到缓存时,替换那个按时间排序最后的对象。
LFU(Least Frequently Used):这种算法是每个对象记录了对象访问的次数(即命中率),当新的对象需要存放到缓存时,替换那个访问次数最少的对象。
FIFO(First In First Out):这种算法是将缓存中的对象存放成一个数组,当新的对象需要存放到内存中是,替换最先存放到缓存的对象。
使用时通常在缓存配置文件中加入:MemoryStoreEvictionPolicy="LRU"