像Hibernate这种ORM框架,相较于JDBC操作,需要有更复杂的机制来实现映射、对象状态管理等,因此在性能和效率上有一定的损耗。

在保证避免映射产生低效的SQL操作外,缓存是提升Hibernate的关键之一。

加入缓存可以避免数据库调用带来的连接创建与销毁、数据打包拆包、SQL执行、网络传输,良好的缓存机制和合理的缓存模式能带来性能的极大提升,EHCache就提供了这种良好的缓存机制。

在考虑给系统加入缓存进行优化前,复用SessionFactory是Hibernate优化最优先、最基础的性能优化方法,参考上一篇《Hibernate性能优化之SessionFactory重用》。

Hibernate的缓存机制


缓存的级别一般分为三种,每一种缓存的范围更大:

事务级缓存:Hibernate中称为一级缓存,在一个Session中共享缓存对象;

应用级缓存:Hibernate中称为二级缓存,在一个SessionFactory中共享缓存对象,SessionFactory在整个应用范围内重用;

分布式缓存:部署为单独的实例,如Redis、Memcache等。

Hibernate的按以下方式进行缓存:

当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查;

查不到,如果配置了二级缓存,那么从二级缓存中查;

如果都查不到,再查询数据库,把结果按照ID放入到缓存删除、更新、增加数据的时候,同时更新缓存。

Hibernate默认不启用二级缓存,EHCache是Hibernate中的二级缓存插件,使用Hibernate的系统可以直接使用EHCache缓存。

为什么要直接使用EHCache


回头来看那句话:良好的缓存机制和合理的缓存模式能带来性能的极大提升。

Hibernate的缓存模式是什么?

根据ID来缓存对象,也就是Session的get、load操作时。

这种缓存模式的弊端有两点:

1、应用场景太单一,系统中大量的列表式查询缓存起不到作用;

2、一些系统中通过ThreadLocal在线程中重用Session,每个线程可能需要大量处理不用的业务逻辑,缓存命中率很低;如果不重用Session,一般的场景缓存命中率更低。

既然EHCache已经提供了良好的缓存机制,结合自己系统的业务来优化缓存模式才是最佳的。

如何使用EHCache


EHCache是Hibernate中的二级缓存插件,使用Hibernate的系统可以直接使用EHCache缓存,不需要再添加其他jar包。

新建EHCache配置文件,具体的配置含义可以查手册:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:noNamespaceSchemaLocation="ehcache.xsd">  <diskStore path="java.io.tmpdir"/>  <defaultCache  maxElementsInMemory="10000"  maxElementsOnDisk="0"  eternal="true"  overflowToDisk="true"  diskPersistent="false"  timeToIdleSeconds="0"  timeToLiveSeconds="0"  diskSpoolBufferSizeMB="50"  diskExpiryThreadIntervalSeconds="120"  memoryStoreEvictionPolicy="LFU"  />  <cache name="restCache"  maxElementsInMemory="100"  maxElementsOnDisk="0"  eternal="false"  overflowToDisk="false"  diskPersistent="false"  timeToIdleSeconds="119"  timeToLiveSeconds="119"  diskSpoolBufferSizeMB="50"  diskExpiryThreadIntervalSeconds="120"  memoryStoreEvictionPolicy="FIFO"  />
</ehcache>  

EHCache的一个优点是线程安全的,适合多线程的使用场景,能简化开发人员的使用。

因此我写了一个单例模式,避免每次在方法里写getCache,这个类也涵盖了EHCache的基本使用:

public class EHCacheFactory {private final CacheManager manager;private final Cache cache;private EHCacheFactory() {manager = CacheManager.create(getClass().getResource("/ehcache.xml"));cache = manager.getCache("restCache");}public Element getCache(String strKey) {return EHCacheFactory.getInstance().getCache().get(strKey);}public void setCache(String strKey, String strVal) {EHCacheFactory.getInstance().getCache().put(new Element(strKey, strVal));}public Cache getCache() {return cache;}private static class SingletonHolder {private final static EHCacheFactory INSTANCE = new EHCacheFactory();}public static EHCacheFactory getInstance() {return SingletonHolder.INSTANCE;}
}

我的系统是JAVA REST,在需要缓冲的REST接口中加入了EHCache缓存,通过URL参数作为缓存键值,REST接口返回的json数据作为缓存值,这种缓存模式非常适合REST。

使用ab进行了简单的性能测试:

在一个简答查询接口中,性能提升一倍;

在一个略复杂接口中,执行4、5个查询,加入缓存后性能提升20倍。

在这里就不贴ab测试结果了,大家可以自行测试一下。


记录,为更好的自己!

转载于:https://www.cnblogs.com/ym123/p/4627435.html

Hibernate性能优化之EHCache缓存相关推荐

  1. Hibernate 性能优化之二级缓存

    二级缓存是一个共享缓存,在二级缓存中存放的数据是共享数据 特性      修改不能特别频繁      数据可以公开 二级缓存在sessionFactory中,因为sessionFactory本身是线程 ...

  2. Yii2性能优化之:缓存依赖

    Yii2性能优化之:缓存依赖 Yii中的缓存依赖,简单来说就是将缓存和另外一个东西绑定在一起,如果另外一个东西发生变化,那么缓存也将发生变化.有点儿类似于JS中的触发事件(但是也不那么像),缓存的变动 ...

  3. Oracle性能优化 以及 库缓存命中率及等待事件

    http://www.cnblogs.com/hyddd/archive/2009/08/30/1556939.html 前言 最近hyddd一直看Oracle的资料,今天特地总结一下这段时间了解到的 ...

  4. Hibernate 性能优化技巧

    在处理大数据量时,会有大量的数据缓冲保存在Session的一级缓存中,这缓存大太时会严重显示性能,所以在使用Hibernate处理大数据量的,可以使用session.clear()或者session. ...

  5. Hibernate性能优化

    有很多人认为Hibernate天生效率比较低,确实,在普遍情况下,需要将执行转换为SQL语句的 Hibernate的效率低于直接JDBC存取,然而,在经过比较好的性能优化之后,Hibernate的性能 ...

  6. SQL性能优化前期准备-清除缓存、开启IO统计

    如果需要进行SQl Server下的SQL性能优化,需要准备以下内容: 一.SQL查询分析器设置: 1.开启实际执行计划跟踪. 2.每次执行需优化SQL前,带上清除缓存的设置SQL. 平常在进行SQL ...

  7. 最常被遗忘的 Web 性能优化:浏览器缓存

    一提起缓存, Web开发者们总是在想数据库缓存.页面静态化.使用 Redis内存缓存.这些方法都有一个共性,就是集中在后台,目的就是加快数据的读取,少用比较容易产生瓶颈的部分. 后台该优化的都优化到了 ...

  8. 前端性能优化之“离线缓存manifest”

    在 本专栏 的 这一篇文章 中,给各位引出了一个"不同寻常的"性能体验优化方式 -- 离线缓存,并介绍了它的简单用法,本文来详细说说! 啥是离线缓存 离线缓存又叫"App ...

  9. 转载:最常被遗忘的 Web 性能优化:浏览器缓存

    https://www.sohu.com/a/153567485_505818 一提起缓存, Web开发者们总是在想数据库缓存.页面静态化.使用 Redis内存缓存.这些方法都有一个共性,就是集中在后 ...

最新文章

  1. TypeScript学习笔记3:运算符
  2. 【转】HashTable 和 HashMap的区别
  3. One order popup window 显示逻辑
  4. C++ - 进阶 1002
  5. 数独java界面基础_java版数独游戏界面实现(二)
  6. 9月安卓机性能榜单公布:华为未进前十,第一名有点意外
  7. 计算机组成原理+左冬红,计算机组成原理与接口技术--基于MIPS架构(第2版高等学校电子信息类专业系列教材)...
  8. 嵌入式开发之视频压缩比---h264、mjpeg、mpeg4
  9. python申明变量和赋值_Python入门(二)
  10. 3-4 掘金小册学习
  11. weblogic 下载和安装
  12. 乌班图系统安装到U盘
  13. 带圆圈的数字和markdown常用表达式记录
  14. php dwg文件,dwf文件怎么转成dwg
  15. hⅰgh怎么读音发音英语_字母h的发音音标
  16. vue中使用ajax全局配置,jQuery和vue 设置ajax全局请求
  17. LearnOpenGL14——混合以及处理半透明物体
  18. apache iotdb_清华数为工业互联网时序数据库Apache IoTDB亮相2019工业互联网峰会
  19. python神经网络分析案例_python神经网络实战
  20. r语言nonzerocoef函数_lars算法R语言操作指南.pdf

热门文章

  1. ES6入门——类的概念
  2. karaf中利用Bundle引入外部log4j配置文件
  3. hdu 4454 Stealing a Cake 三分法
  4. Android之播放一首简单的音乐
  5. Mybatis01(结果集封装)
  6. BitMap-BitSet(JDK1.8)基本使用入门
  7. Hbase集群安装Version1.1.5
  8. accounts/login/?next=/account/password-change/
  9. java 中数组的创建 数组遍历 以及数组的输出(打印)
  10. 父元素遮住子元素的问题