2013-10-22 199 views

回答

1

一级高速缓存默认情况下处于启用状态,并且是基于每个会话的。查询缓存默认情况下未启用,在多个会话中共享,应始终与第二级缓存一起使用。

要启用查询缓存,以下性能应使用:

hibernate.cache.use_second_level_cache=true 
hibernate.cache.use_query_cache=org.hibernate.cache.EhCacheProvider 
hibernate.cache.use_query_cache=true 
5

是的,是不同的东西。 就像Lee Chee Kiam所说的,一级缓存默认是启用的,你不能禁用它。 基本上它是Hibernate在第一次放置取出的实体的位置,因此同一对象的第二个查询不会实例化一个新对象,甚至可以通过ID避免查询。有关此here的示例。

//Open the hibernate session 
Session session = HibernateUtil.getSessionFactory().openSession(); 
session.beginTransaction(); 

//fetch the department entity from database first time 
DepartmentEntity department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); 
System.out.println(department.getName()); 

//fetch the department entity again 
department = (DepartmentEntity) session.load(DepartmentEntity.class, new Integer(1)); 
System.out.println(department.getName()); 

session.getTransaction().commit(); 
HibernateUtil.shutdown(); 

Output: 

Hibernate: select department0_.ID as ID0_0_, department0_.NAME as NAME0_0_ from DEPARTMENT department0_ where department0_.ID=? 
Human Resource 
Human Resource 

我们可以说第一级缓存是IdentityMap模式的Hibernate实现。

查询缓存与实体严格相关,它在搜索条件和满足特定查询过滤器的实体之间绘制关联(来自here)。 查询缓存仅将查询的原始结果保存为主键,在hibernate speak,id's中。 它不包含实际的水合物

查询缓存如何工作?

假设我们有以下的条件查询:

session.createCriteria(Person.class) 
    .add(Restrictions.eq("firstName", "Joey") 
    ).setCacheable(true); 

查询缓存看起来概念等,其中的关键是通过查询文本和参数值组成的哈希表,并将该值是实体的名单ID匹配查询

*----------------------------------------------------------* 
|      Query Cache      |      
|----------------------------------------------------------| 
| ["from Person where firstName=?", ["Joey"] ] -> [1, 2] ] | 
*----------------------------------------------------------* 

所以,下一次我们执行相同的标准查询的,Hibernate会看那个哈希表,并解决了与人ID 1和2匹配的限制。 在这种情况下,你会避免查询的成本(在这种情况下,几乎为零,但可能是一个昂贵的查询与连接等),但你仍然会击中数据库查询人员(现在通过ID什么非常快)用于构建Person对象。 查询缓存经常与第二级缓存一起使用,这需要第三部分实现,如Ehcache或infinispan。

二级缓存存储实体数据,但不是实体本身。数据以“脱水”格式存储,看起来像一个哈希映射,其中键是实体Id,并且该值是原始值列表。 这里是一个如何的二级高速缓存查找的内容的例子:

*-----------------------------------------* 
|   Person Data Cache    | 
|-----------------------------------------| 
| 1 -> [ "Joey" , "Q" , "Public" , null ] | 
| 2 -> [ "Joey" , "D" , "Public" , 1 ] | 
| 3 -> [ "Sara" , "N" , "Public" , 1 ] | 
*-----------------------------------------* 

因此,查询缓存会为我们提供了ID为1和2,然后Hibernate会构造对象与在原始数据二级缓存,对应于id为1和2的人。

查询缓存和第二级缓存适用于具有多个读取且很少或零更新的实体。因为众所周知的每种缓存类型都存在不一致的问题。因此,Hibernate将需要使缓存或刷新缓存无效(如果您有群集缓存,则包含复制)。随着许多更新,你会不断地使缓存无效,它会做得更多的伤害,而不是好的。

从这个great post得到了一些解释,你也应该阅读这good answer