Hibernate 菜鸟教程走进HibernateBuilding Evolutionary Architectures

Hibernate缓存

2018-01-06  本文已影响11人  刘亚涛

概述

Hibernate Cache 对于提高应用的性能是非常有用的。缓存的目标就是减少数据库的查询,从而减少应用的吞吐时间。Hibernate提供如下几种缓存类型

一级缓存 二级缓存

一级缓存

Session session = sessionFactory.openSession();

//第一次查询数据库
session.get(Employee.class, 1L);

Thread.sleep(2000);

//第二次不查询数据库
session.get(Employee.class, 1L);

session.close();

在同一个session中当对象的实例存在时将会直接返回实例,并不会再次执行查询数据库操作。但是hibernate提供了清除缓对象实例的方法,它们是:

Session session = sessionFactory.openSession();

//第一次查询数据库
session.get(Employee.class, 1L);

Thread.sleep(2000);
        
//清除一级缓存
session.clear();
// or session.evict(employee);

//第二次查询数据库,因为一级缓存已经被清除
session.get(Employee.class, 1L);
session.close();

二级缓存

二级缓存的作用域是 Session Factory

一个事务产生的二级缓存可以在两一个事务中直接访问到。现在做如下测试(设置缓存策略为只读):

Session session = sessionFactory.openSession();
Session otherSession = sessionFactory.openSession();

Statistics statistics = sessionFactory.getStatistics();
statistics.setStatisticsEnabled(true);


//开启第一个事务
Transaction transaction = session.beginTransaction();

//第一次查询数据库
Employee employee= session.get(Employee.class, 1L);
print("第一次从数据库中查询",statistics);

//第二次从一级缓冲中查询
session.get(Employee.class, 1L);
print("第二次从一级缓冲中查询",statistics);

//清除一级缓存
session.evict(employee);

/从二级缓存中查询
session.get(Employee.class, 1L);
print("从二级缓存中查询",statistics);

//提交第一个事务
transaction.commit();
session.close();

        

//第二个事务
Transaction otherTransaction = otherSession.beginTransaction();

otherSession.get(Employee.class, 1L);
print("另一个事务",statistics);

otherSession.get(Employee.class, 2L);
print("查询另一条记录",statistics);

//提交第二个事务
otherTransaction.commit();
otherSession.close();

最终结果为:

执行结果

Region Factory

Hibernate的二级缓存是对真实的缓存提供者(cache provider)透明的,org.hibernate.cache.spi.RegionFactory接口囊括了缓存提供者应该实现的各种细节,该接口其实是Hibernate和缓存提供者的一个桥梁。比较知名的缓存提供者有:

Hibernate二级缓存策略

缓存管理

如果没有设置缓存过期(expiration)和缓存释放(eviction)策略,缓存将会一致增加直到耗尽所有内存。通常情况下Hibernate将缓存管理的职责转交给缓存提供者(Cache Provider)。

集合的缓存

默认情况下集合是不会被缓存的,只有明确地标注为可缓存,该集合对象才能被缓存。

缓存状态内部的内部表征

实体并没有缓存实体的对象实例到二级缓存中,而是拆散(disassembled)的状态,返回缓存的时候需要重新组装(assembly)。

这种设计只是反映了潜在的对应关系,这样提高了空间利用率,同时也方便关联的实体类的协调。

集合缓存的内部表征

在一对多,多对多的集合需要显式地指出才会被缓存。其实Hibernate将每一个集合的缓存放在其他的缓存域中,而不是该实体对象所在的缓存域中,集合缓存域的名称由类名+集合的属性名组成,通过域的名字可以查看到缓存的数据。

还有需要指出的是,只有集合中各个对象的主键会被缓存,然后通过这些主键再去查找对象的其他属性,因此最好把集合中的实体类也设置成可被缓存。

查询缓存

可以HQL 的查询结果也缓存起来,当要经常查询很少发生变大的数据集时做查询缓存是很有用的。要启动查询缓存只要设置hibernate.cache.use_query_cache属性为true即可。

查询缓存的最佳实践

参考资料

最后

感谢阅读,写作能力有限,如有需要可以扫描下方二维码并关注公众账号与作者取得联系。

扫码关注
上一篇 下一篇

猜你喜欢

热点阅读