hibernate  :

Hibernate是一个持久层框架,经常访问物理数据库。

为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。

缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。

Hibernate缓存包括两大类:Hibernate一级缓存和L1Hibernate二级缓存 L2。

1.Hibernate一级缓存又称为“Session的缓存”。

Session内置不能被卸载,Session的缓存是事务范围的缓存(Session对象的生命周期通常对应一个数据库事务或者一个应用事务)。

一级缓存中,持久化类的每个实例都具有唯一的OID。

注意:在进行ssh整合的过程中spring管理hibernate的一级缓存是无效的。

重点hibernate的二级缓存,搜了很多博客 结果很坑,概念理解解释都没错,关键就是配置,可能是我的hibernate的版本过高的原因,导致配置失败。

二级缓存的大致可以分为一下几类:

  • 事务缓存:作用于事务范围,session结束则缓存清除,Hibernate的L1缓存为事务缓存,默认开启,我们在纯Hibernate项目中手写过回滚的代码,能够回滚就是因为事务缓存。
  • 应用缓存:作用于应用范围,被所有事务共享,依赖于应用的生命周期。所以,非常适合使用一个同样依赖于应用生命周期的轻量级缓存来实现,ehcache几乎是最好的选择。
  • 集群缓存:该缓存类似于真正的数据库被一个集群共享,典型的如Redis就很适合做集群缓存

二级缓存的工作原理;

Hibernate的L1,L2缓存均是通过id进行工作,当Hibernate根据id访问对象时会先在一级缓存中查找,如果查不到则在二级缓存中查找。

SessionFactory二级缓存根据功能和目的又可以划分为内置缓存和外置缓存,内置缓存存放映射元数据和预定义SQL语句,

前者为映射文件中数据的副本,后者为根据副本推导出的SQL语句。内置缓存是只读的,因此不需要与映射文件进行同步。

外置缓存是Hibernate的一个插件,默认不启用,即Hibernate的L2缓存。外置缓存的数据是数据库数据的副本,外置缓存的介质可以是内存或者硬盘。

2,废话不多说,使用外部插件Ehcache开启hibernate的二级缓存

Ehcache是一个健壮的简洁的轻量的纯Java进程的内存缓存框架,因此其存在与Java进程直接相关联。

通过在硬盘和内存里对数据进行拷贝,实现了数据库的缓存。由于Apache的支持,Ehcache非常稳健。

pom节点:

<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.1.7.Final</version>
</dependency> <dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.3.1</version>
</dependency>

编写:ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache> <diskStore path="D:/ehcache"/> <defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/> <cache name="sampleCache1"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/> <cache name="sampleCache2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> </ehcache>

ehcache的各属性介绍如下:

  • name:缓存名称。
  • maxElementsInMemory:缓存最大个数。
  • eternal:对象是否永久有效,一但设置了,timeout将不起作用。
  • timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  • timeToLiveSeconds:设置对象在失效前允许存活时间,最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0,也就是对象存活时 间无穷大。
  • overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
  • diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  • maxElementsOnDisk:硬盘最大缓存个数。
  • diskPersistent:是否缓存虚拟机重启期数据,默认false。
  • diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  • memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU。你可以设置为 FIFO或是LFU。
  • clearOnFlush:内存数量最大时是否清除。

在spring管理的sessionFactory中开启二级缓存

   <bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>zy.entity</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!-- 博客地址 :http://www.cnblogs.com/fsh1542115262/articles/6071470.html hibernate.current_session_context_class三种配置-->
<prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</prop>
<!-- 避免这个错误信息Disabling contextual LOB creation as createClob() method threw error :java.lang.reflect.InvocationTargetException -->
<prop key="hibernate.temp.use_jdbc_metadata_defaults">false</prop>
<!--开启hibernate的二级缓存-->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<!--设置缓存的类型,设置缓存的提供商 EhCacheRegionFactory--> </props>
</property>
</bean>

其中

<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>这个是关键所在,之前之所以配置不成功的原因是因为我的hibernate的版本过高,而高版本早就替换成
hibernate.cache.region.factory_class指定的ehcache的工厂。
  • hibernate.cache.use_second_level_cache 是hibernate中L2缓存的开关,必须为true。
  • hibernate.cache.use_query_cache 是hibernate的查询缓存的开关,可以自己决定是否开启。
  • hibernate.cache.region.factory_class 承载L2缓存的方法,即选择L2缓存数据库。官方很坑的从hibernate4开始就存在文档问题,文档中仍为provider_class,实际上早已换为了这个方法(idea的默认提示中找不到,但运行后如果没添加,错误日志里可以显示出)。需要注意的是,需要使用Singleton模式的Factory,否则会有冲突问题。具体原因还不明了。

另外有几个可以开启的选项,包括

  • hibernate.generate_statistics 生成统计日志,如果项目在调试,这是一个很好的开发选项。记得实际运行时关闭掉。
  • hibernate.cache.provider_configuration_file_resource_path 提供配置文件的路径,如果你不想使用默认路径,那么需要在这里配置,其格式和web.xml中的路径一致。

另外一个就是需要在缓存的实体中设置缓存策略:

ehcache不支持事务,有三种模式:

  • READ_ONLY: 适用于仅读取,如果有数据的更新操作则会异常。
  • READ_WRITE: 用读写锁控制缓存
  • NON_STRICT_READ_WRITE: 不加锁控制缓存,写写会有冲突,适用于很难发生写冲突的系统。

具体使用时,在hibernate持久化生成的Entity上使用类似这样的标签,即可为该数据库添加二级缓存。

注解方式:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

  xml方式:
<cache usage="read-write"/>  包括类级别和集合级别;
通常情况下,缓存用于多读少写的表,在这种表中,最高效,最符合缓存本身行为的应该是READ_ONLY模式,即,在读取时使用缓存,发生写操作时清空缓存。 测试:hibernate中默认使用 二级缓存的方法load()和iterator()方法
这里使用load()方法配置:
我dao层方法:
    public Bill load() {
Session session = this.sessionFactory.openSession();
Bill load = session.load(Bill.class, 24);
/* if(!Hibernate.isInitialized(load)){
Hibernate.initialize(load);
}
session.close();*/
return load;
}
    /**
* 测试hibernate的二级缓存
*/
@Test
public void TestTwoCache(){
ApplicationContext context = new ClassPathXmlApplicationContext("spring-hiberanate.xml");
BillService service= (BillService)context.getBean("billServiceImpl");
Bill load = service.load();
System.out.println(load);
System.out.println(load.getBname());
System.out.println("----------------------------------"); //注意这不是调用的一级缓存,因为在ssh整合中hibernate的一级缓存是失效的包括ssm 就是mybatis
BillService service1= (BillService)context.getBean("billServiceImpl");
Bill load1 = service.load();
System.out.println(load1.getBname());
}

运行结果:

Hibernate: select bill0_.bid as bid1_1_0_, bill0_.bmoney as bmoney2_1_0_, bill0_.bname as bname3_1_0_, bill0_.createtime as createti4_1_0_, bill0_.hscode as hscode5_1_0_, bill0_.paystate as paystate6_1_0_, bill0_.scount as scount7_1_0_, bill0_.sunit as sunit8_1_0_, bill0_.supId as supId9_1_0_ from bill bill0_ where bill0_.bid=?
zy.entity.Bill@374ffe34
猕猴桃山西
----------------------------------
猕猴桃山西

很明显hibernate的二级缓存设置成功;

项目下载地址:算了吧。。太low  如果有需要,留评论;

ssh整合hibernate 使用spring管理hibernate二级缓存,配置hibernate4.0以上二级缓存的更多相关文章

  1. Spring管理Hibernate

    为什么要用Hibernate框架? 既然用Hibernate框架访问管理持久层,那为何又提到用Spring来管理以及整合Hibernate呢? 首先我们来看一下Hibernate进行操作的步骤.比如添 ...

  2. spring管理hibernate session的问题探究

    我们再用spring管理hibernate的时候, 我们会继承HibernateDaoSupport 或者HibernateTemplate类. 我们不知道这两个类之间有什么关系. 也没有去关闭ses ...

  3. SSH程序框架之Spring与HIbernate整合

    spring整合hibernate 有两种方式 1.注解方式 2.xml方式实现 Spring整合Hibernate有什么好处? 1.由IOC容器来管理Hibernate的SessionFactory ...

  4. SSH整合方案二(不带hibernate.cfg.xml)

    整体结构: 1.引入相关jar包 2.编写实体类和映射文件 package cn.zqr.domain; public class Customer { private Long cust_id; p ...

  5. spring管理hibernate,mybatis,一级缓存失效原因

    mybatis缓存:一级缓存和二级缓存 hibernate缓存:一级缓存和二级缓存 关于缓存: 缓存是介于物理数据源与应用程序之间,是对数据库中的数据复制一份临时放在内存中的容器, 其作用是为了减少应 ...

  6. Spring管理Hibernate事务

    在没有加入Spring来管理Hibernate事务之前,Hibernate对事务的管理的顺序是: 开始事务 提交事务 关闭事务 这样做的原因是Hibernate对事务默认是手动提交,如果不想手动提交, ...

  7. Spring管理 hibernate 事务配置的五种方式

    Spring配置文件中关于事务配置总是由三个组成部分,DataSource.TransactionManager和代理机制这三部分,无论是那种配置方法,一般变化的只是代理机制这块! 首先我创建了两个类 ...

  8. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:0.概述

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 序言 帖主和队友仿制了一个简单版的微信,其中,队友是用Unity3D做前段,帖主用Java的Mina.Hiberna ...

  9. SSH整合报错:org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped[......]

    非常诡异的报错,信息如下:org.hibernate.hql.internal.ast.QuerySyntaxException: User is not mapped [select count(* ...

随机推荐

  1. [转帖]Windows批处理(cmd/bat)常用命令小结

    Windows批处理(cmd/bat)常用命令小结 非常值得学习的文档 先放这里 有时间做实验, 转载自:“趣IT”微信公共号 前言 批处理文件(batch file)包含一系列 DOS命令,通常用于 ...

  2. day 7-17 多表查询

    一. 准备表 #部门表 create table dep( id int, name varchar(20) ); #员工表 create table emp( id int primary key ...

  3. .Net的EF+MVC框架使用T4生成各个层的代码的,在新增表的时候,调不到新增的实体

    如果确认有这个实体的话,只需要把T4模板全部重新生成就可以了

  4. Some beautiful Progress Bars in WPF

    1.Better WPF Circular Progress Bar 2.Bending the WPF ProgressBar 3.A CIRCULAR PROGRESSBAR STYLE USIN ...

  5. idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml,

    第一种错误 :idea中 maven打包时时报错User setting file does not exist C:\Users\lenevo\.m2\setting.xml, 解决方案如下:将ma ...

  6. git(命令行常用炒作)

    Git常用操作 https://backlog.com/git-tutorial/cn/intro/intro1_1.html Git详解(思维导图) https://blog.csdn.net/hu ...

  7. 用python写一个预警机器人(支持微信和钉钉)

    背景 线上的系统在运行中,发生故障时怎么及时的通过手机通知到相关人员?当然这是个很简单的需求,现有的方法有很多,例如: 如果我们用的云产品,那么一般都会有配套对应的监控预警功能,根据需要配置一下即可, ...

  8. 如何在MAC上运行exe程序

    1. 首先下载并运行CrossOver 运行CrossOver需要收费,试用期为14天,运行CrossOver 2. 选择exe应用程序,新建容器,安装exe程序 3.安装成功后,运行exe应用程序启 ...

  9. Announcing Windows Template Studio in UWP

    今天,我们很高兴地宣布您的文件→新的通用Windows平台应用程序在Visual Studio - Windows模板工作室中的下一个演变.Windows Template Studio在开发人员调查 ...

  10. Nginx geoip模块

    需要编译进 --with-http_geoip_module 首先要安装maxMind里的geoip的c开发库 https://dev.maxmind.com/geoip/legacy/downloa ...