开始使用Hibernate的人们常见的问题之一就是性能,如果您没有太多的Hibernate经验,您会发现应用程序变慢的速度。 如果启用sql跟踪,您将看到有多少查询被发送到数据库,而这些查询几乎不需要Hibernate知识就可以避免。 在当前文章中,我将解释如何使用休眠查询缓存来避免应用程序和数据库之间的通信量。

Hibernate提供了两个缓存级别:

  • 一级缓存是会话缓存。 对象被缓存在当前会话中,并且它们仅在会话关闭之前是活动的。
  • 只要会话工厂处于活动状态,第二级缓存就存在。 请记住,在Hibernate情况下,二级缓存不是对象树。 对象实例不被缓存,而是存储属性值。

在简要介绍了一下Hibernate缓存之后(让我知道这很简短),让我们看一下什么是查询缓存以及如何与二级缓存相关联。

查询缓存负责将作为参数提供的查询和值的组合作为键进行缓存,并将查询执行返回的对象的标识符列表作为值进行缓存。 注意,使用查询缓存也需要二级缓存,因为从缓存(即标识符列表)获取查询结果时, Hibernate将使用二级缓存的标识符加载对象。

概括起来,作为一个概念性的模式,给出下一个查询:“ from country from country>:number “,第一次执行后, Hibernate缓存将包含下一个虚构值(请注意,number参数设置为1000):

L2快取
[
id:1,{name ='Spain',人口= 1000,...。} id:2,{name ='德国',人口= 2000,...} …。 QueryCache [{来自人口>:number的国家/地区,1000},{id:2}]

因此,在开始使用查询缓存之前,我们需要配置第二级缓存。
首先,您必须确定要使用的缓存提供程序。 对于此示例,选择了Ehcache ,但请参阅Hibernate文档以获取所有支持的提供程序的完整列表。

要配置二级缓存,请设置下一个休眠属性:

hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
hibernate.cache.use_structured_entries = true
hibernate.cache.use_second_level_cache = true

如果您使用注释方法,请使用以下方法注释可缓存的实体:

@可缓存
@Cache(用法= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)

可以看到在这种情况下,缓存并发策略是NONSTRICT_READ_WRITE ,但是根据缓存提供者的不同,可以遵循其他策略,例如TRANSACTIONAL,READ_ONLY ………请查看Hibernate文档的缓存部分,以选择最适合您需求的策略。

最后添加Ehcache依赖项:

<依赖性>
<groupId> net.sf.ehcache </ groupId>
<artifactId> ehcache-core </ artifactId> <version> 2.5.0 </ version> </ dependency> <依赖性> <groupId> org.hibernate </ groupId> <artifactId> hibernate-ehcache </ artifactId> <version> 3.6.0.Final </ version> </ dependency>

现在已配置了二级缓存,但未配置查询缓存 ; 无论如何,我们离目标不远。

hibernate.cache.use_query_cache属性设置为true

对于每个可缓存的查询,我们必须在查询创建期间调用setCachable方法:

List <Country> list = session.createQuery(“来自人口> 1000的国家/地区”).setCacheable(true).list();

为了使示例更实用,我已经使用Spring Framework上传了完整的查询缓存示例。 为了清楚地了解查询缓存的工作原理,我使用了一个在ensembl.org中托管的公共数据库。 Ensembl项目为脊椎动物和其他真核生物建立了基因组数据库,并在线免费提供此信息。 在此示例中,对dna表的查询被缓存。

首先进行Hibernate配置:

@Configuration
public class HibernateConfiguration {@Value("#{dataSource}")private DataSource dataSource;@Beanpublic AnnotationSessionFactoryBean sessionFactoryBean() {Properties props = new Properties();props.put("hibernate.dialect", EnhancedMySQL5HibernateDialect.class.getName());props.put("hibernate.format_sql", "true");props.put("hibernate.show_sql", "true");props.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");props.put("hibernate.cache.use_structured_entries", "true");props.put("hibernate.cache.use_query_cache", "true");props.put("hibernate.cache.use_second_level_cache", "true");props.put("hibernate.hbm2ddl.auto", "validate");AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();bean.setAnnotatedClasses(new Class[]{Dna.class});  bean.setHibernateProperties(props);bean.setDataSource(this.dataSource);bean.setSchemaUpdate(true);return bean;}}

这是一个简单的Hibernate配置,使用前面说明的属性来配置二级缓存。

实体类是代表DNA序列的实体。

@Entity(name="dna")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Dna {@Idprivate int seq_region_id;private String sequence;public int getSeq_region_id() {return seq_region_id;}public void setSeq_region_id(int seq_region_id) {this.seq_region_id = seq_region_id;}@Columnpublic String getSequence() {return sequence;}public void setSequence(String sequence) {this.sequence = sequence;}}

为了尝试查询缓存 ,我们将实现一项测试,其中多次执行同一查询。

@Autowired
private SessionFactory sessionFactory;@Test
public void fiftyFirstDnaSequenceShouldBeReturnedAndCached() throws Exception {for (int i = 0; i < 5; i++) {Session session = sessionFactory.openSession();session.beginTransaction();Time elapsedTime = new Time("findDna"+i);List<Dna> list = session.createQuery("from dna").setFirstResult(0).setMaxResults(50).setCacheable(true).list();session.getTransaction().commit();session.close();elapsedTime.miliseconds(System.out);for (Dna dna : list) {System.out.println(dna);}}
}

我们可以看到我们正在返回前五十个dna序列,如果执行它,您将看到打印了从查询创建到提交事务之间的经过时间。 如您所料,仅第一次迭代就需要大约5秒钟来获取所有数据,而其他迭代只需数毫秒。

查询迭代之前的foreach行将通过控制台打印对象标识符。 如果仔细观察,这些标识符将不会在所有执行期间重复。 这个事实只是向您显示Hibernate缓存不会保存对象而是保存属性值,并且每次都会创建对象本身。

最后一点,请记住,默认情况下, Hibernate不缓存关联。

现在,在编写查询之后,考虑它是否将包含静态数据以及是否将经常执行。 在这种情况下, 查询缓存是您的朋友,可以使Hibernate应用程序运行得更快。

下载代码

参考:来自JCG合作伙伴的 Hibernate缓存级别教程   在一个罐子统治他们所有博客的亚历克斯·索托。

翻译自: https://www.javacodegeeks.com/2012/02/hibernate-cache-levels-tutorial.html

Hibernate缓存级别教程相关推荐

  1. Hibernate缓存原理与策略 Hibernate缓存原理:

    Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...

  2. Hibernate 缓存机制

    转载:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...

  3. hibernate官方新手教程 (转载)

    hibernate官方新手教程第一部分 - 第一个Hibernate程序 首先我们将创建一个简单的控制台(console-based)Hibernate程序.我们使用内置数据库(in-memory d ...

  4. 【大话Hibernate】hibernate缓存详解

    为什么要用hibernate缓存? hibernate是一个持久层框架,经常访问物理数据库.为了降低应用程序对物理数据源访问的次数,从而提高应用程序的运行性能,我们想到使用hibernate缓存机制. ...

  5. (11) Hibernate 缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  6. 初识Hibernate 缓存

    生活就像一杯咖啡,让你我慢慢的品尝,品尝它的苦涩和甘甜...... 一.什么是Hibernate缓存. 解析:白话来说就是缓存数据的容器 官方标准点缓存:是计算机领域的概念,它介于应用程序和永久性数据 ...

  7. hazelcast 使用_使用HazelCast进行Hibernate缓存:JPA缓存基础知识

    hazelcast 使用 HazelCast的最大功能之一就是对Hibernate第二级缓存的支持 . JPA具有两个级别的缓存. 一级缓存在事务期间缓存对象的状态. 通过两次查询相同的对象,您必须获 ...

  8. gwt-2.8.2下载_GWT 2 Spring 3 JPA 2 Hibernate 3.5教程– Eclipse和Maven 2展示

    gwt-2.8.2下载 不久前,我的一个朋友和同事向我飞过,说"世界上只有一半在使用Maven ". 当我意识到最受欢迎的文章(到目前为止) GWT 2 Spring 3 JPA ...

  9. gwt-2.8.2下载_GWT 2 Spring 3 JPA 2 Hibernate 3.5教程

    gwt-2.8.2下载 本分步指南将介绍如何使用以下方法开发简单的Web应用程序 Google的网络工具包 (GWT)用于富客户端,而Spring作为后端服务器端框架. 该示例Web应用程序将提供对数 ...

最新文章

  1. 在Intellij Idea中使用jstl标签库
  2. c++ vector 中的坑
  3. 04-多核多cluster多系统之间缓存一致性概述
  4. java 正则 子字符串_使用Java正则表达式来查找另一个子字符串中的子字符串
  5. [蓝桥杯2017初赛]纸牌三角形-枚举permutation+数论
  6. 控制台应用和空项目有什么区别_在公司做的项目和自己在学校做的有什么区别?...
  7. Linux中grep命令详解
  8. android 微信分享小程序 图片显示不全
  9. 南信大校园网稳定|多拨|软路由|硬路由|保姆级教学|一步到位|openwrt|pandavan老毛子
  10. 全新帝国CMS7.5大气科技感网站建设+网络公司网站源码
  11. ppt显示无法连接服务器文件路径,ppt打开时显示“此演示文稿包含到其他文件的链接”弹出框是什么原因?...
  12. 0x0000011b共享打印机无法连接解决方法
  13. Flink Watermark机制
  14. 记录一下unity 加载外部视频
  15. 第4章 序言的具体写法
  16. matlab中主程序如何调用其它子程序,主程序怎样调用子程序
  17. Java经典“羊车门”概率问题解答
  18. Linux的安装与系统介绍
  19. 共赢云时代——用友能源耕云计划全国行河南站圆满结束
  20. 如何通过几何画板绘制双曲线

热门文章

  1. java流写入数据库_使用Java流查询数据库
  2. api网关和esb区别_具有ESB,API管理和Now .. Service Mesh的应用程序网络功能。
  3. java关键字和标识符_Java数据类型和标识符
  4. java streams_使用JShell的Java 9 Streams API
  5. gwt格式_GWT HTTP请求替代方案
  6. 使用JSON模式验证来映射稀疏JSON
  7. 断言工具的编写_编写干净的测试–用特定领域的语言替换断言
  8. java与java ee_使用Java EE的ManagedExecutorService异步执行事务
  9. 为特使建立控制平面的指南-部署权衡
  10. activemq 实例_在一台计算机上运行多个ActiveMQ实例