hibernate缓存
Hibernate提供了一级缓存和二级缓存,合理的利用缓存可以有助于提高系统的性能,为了避免不合理的利用缓存导致内存过度消耗降低系统性能,可以通过合理配置缓存的参数来避免这个问题。
缓存的目的是为了通过减少应用程序对物理数据访问的次数来提高程序运行的效率,原理则是把当前或接下来一段时间有可能会用到的数据保存到内存中,在使用时直接从内存中读取,而不是从硬盘上读取,简单说,缓存就是数据库中的数据在内存中的“临时容器”。
一级缓存
Hibernate中的一级缓存由Session管理,二级缓存由SessionFactory来管理。在使用时,二级缓存是可有可无的,但一级缓存是必不可少的。
适用还环静
当使用Session查询数据时,首先会在Session内部查找该对象是否存在,若存在,则直接返回,否则,就到数据库中查询,并将查询到的结果缓存起来以便后期使用。一级缓存的缺点就是当使用Session来表示一次会话时,它的生命周期较短,而且它不是线程安全的,不能被多个线程共享,因此,在实际使用时,对效率的提升不是非常明显。
二级缓存
鉴于以上原因,引入二级缓存的概念。二级缓存用来为Hibernate配置一种全局的缓存,以便实现多个线程与实务共享。在使用了二级缓存机制后,当查询数据时,会首先在内存缓存中查找,如果不存在,接着在二级缓存中查找,最后才去数据库中查找。与一级缓存相比,二级缓存还是独立于Hibernate的软件部件,属于第三方的产品,常见的产品有EhCache、OSCache、JbossCache等。Hibernate3默认使用的产品是EhCache。在使用时,可以根据需求通过配置缓存插件实现二级缓存功能,Hibernate为了集成这些插件,提供了org.hibernate.cache.CacheProvider接口来充当缓存插件与Hibernate之间的适配器。当然,二级缓存除了以内存作为存储介质外,还可以选用硬盘等外部存储设备。
二级缓存出现的场景
数据量较小。(数据量太大会消耗大量内存,造成内存资源紧张,降低系统性能)
对数据的修改较少。(会造成频繁对缓存中的数据进行同步,影响系统的性能)
不会被大量的应用共享的数据。(数据被大量线程或事务共享,多线程访问的同步机制会影响系统性能)
不是很重要的数据。(如果要查询的数据对正确性要求较高,如财务,最好不要使用二级缓存)
为什么需要缓存
1.提高性能
2.加快查询速度
介绍一下数据库的类型:
关系型数据库:数据与数据之间存在关系(联系)的数据库 mysql/Oracle、sqlserver
非关系型数据库:数据与数据之间是不存在关系的,key-value
1、基于文件存储的数据库:ehcache
2、基于内存存储的数据库:redis、memcache
3、基于文档存储的数据库:mongodb
2. 什么样的数据需要缓存
很少被修改或根本不改的数据 数据字典
业务场景比如:耗时较高的统计分析sql、电话账单查询sql等
ehcache
Ehcache 是现在最流行的纯Java开源缓存框架,配置简单、结构清晰、功能强大
注1:本章介绍的是2.X版本,3.x的版本和2.x的版本API差异比较大
ehcache的特点:
1 够快
Ehcache的发行有一段时长了,经过几年的努力和不计其数的性能测试,Ehcache终被设计于large, high concurrency systems.
2 够简单
开发者提供的接口非常简单明了,从Ehcache的搭建到运用运行仅仅需要的是你宝贵的几分钟。其实很多开发者都不知道自己用在用Ehcache,Ehcache被广泛的运用于其他的开源项目
3 够袖珍
关于这点的特性,官方给了一个很可爱的名字small foot print ,一般Ehcache的发布版本不会到2M,V 2.2.3 才 668KB。
4 够轻量
核心程序仅仅依赖slf4j这一个包,没有之一!
5 好扩展
Ehcache提供了对大数据的内存和硬盘的存储,最近版本允许多实例、保存对象高灵活性、提供LRU、LFU、FIFO淘汰算法,基础属性支持热配置、支持的插件多
6 监听器
缓存管理器监听器 (CacheManagerListener)和 缓存监听器(CacheEvenListener),做一些统计或数据一致性广播挺好用的
7 分布式缓存
从Ehcache 1.2开始,支持高性能的分布式缓存,兼具灵活性和扩展性
例子
配置文件:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xyx</groupId>
<artifactId>T224_Hibernate</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>T224_Hibernate Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<servlet.version>4.0.0</servlet.version>
<hibernate.version>5.2.12.Final</hibernate.version>
<mysql.driver.version>5.1.46</mysql.driver.version>
<ehcache.version>2.10.0</ehcache.version>
<slf4j-api.version>1.7.7</slf4j-api.version>
<log4j-api.version>2.9.1</log4j-api.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${
junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>${
servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${
hibernate.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${
mysql.driver.version}</version>
</dependency>
<dependency>