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节点:

  1. <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
  2. <dependency>
  3. <groupId>org.hibernate</groupId>
  4. <artifactId>hibernate-ehcache</artifactId>
  5. <version>5.1.7.Final</version>
  6. </dependency>
  7.  
  8. <dependency>
  9. <groupId>org.ehcache</groupId>
  10. <artifactId>ehcache</artifactId>
  11. <version>3.3.1</version>
  12. </dependency>

编写:ehcache.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache>
  3.  
  4. <diskStore path="D:/ehcache"/>
  5.  
  6. <defaultCache
  7. maxElementsInMemory="10000"
  8. eternal="false"
  9. timeToIdleSeconds="120"
  10. timeToLiveSeconds="120"
  11. overflowToDisk="true"
  12. />
  13.  
  14. <cache name="sampleCache1"
  15. maxElementsInMemory="10000"
  16. eternal="false"
  17. timeToIdleSeconds="300"
  18. timeToLiveSeconds="600"
  19. overflowToDisk="true"
  20. />
  21.  
  22. <cache name="sampleCache2"
  23. maxElementsInMemory="1000"
  24. eternal="true"
  25. timeToIdleSeconds="0"
  26. timeToLiveSeconds="0"
  27. overflowToDisk="false"
  28. />
  29.  
  30. </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中开启二级缓存

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

其中

  1. <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上使用类似这样的标签,即可为该数据库添加二级缓存。

注解方式:

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

运行结果:

  1. 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=?
  2. zy.entity.Bill@374ffe34
  3. 猕猴桃山西
  4. ----------------------------------
  5. 猕猴桃山西

很明显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. Notepad++ 安装 NppFTP 插件

    How to install a plugin The plugin (in the DLL form) should be placed in the \plugins subfolder of t ...

  2. K3BOM跳层

    A自制件,B自制件,C外购件 ,结构为A-B-C 如果需要跳层,则设置A-B跳层,B-C跳层,则生成A计划订单,C计划订单, 假设单独A-B跳层,则MRP运算出的结果也是A计划订单,B计划订单,C计划 ...

  3. python爬虫scrapy的LinkExtractor

    使用背景: 我们通常在爬去某个网站的时候都是爬去每个标签下的某些内容,往往一个网站的主页后面会包含很多物品或者信息的详细的内容,我们只提取某个大标签下的某些内容的话,会显的效率较低,大部分网站的都是按 ...

  4. Session和Cookie介绍及常见httpcode

    Cookie和Session,及常见httpcode 1.cookie和session简介: cookie是放在客户端的键值对,用来识别用户信息的,主要包括:名字,值,过期时间,路径和域.路径与域一起 ...

  5. 如何在集合中巧用Where来查找相关元素

    在我们的项目中我们经常会查找一些集合中的重要元素,当然我们可以使用常规的foreach循环和if语句来查询,但是我们要学会使用System.Linq命名空间下面的静态类Enumerable下面的静态方 ...

  6. ES 6 系列 - 变量声明

    let 和 const let 声明 (一)基本用法 let 声明的变量只在块级作用域内有效,出了该块则报错,最常见且适合的地方在 for 循环中: var a = []; for (var i = ...

  7. Centos虚拟环境工具virtualenvwrapper

    下载安装virtualenvwrapper pip3 install virtualenvwrapper !!!!注意安装virtualenvwrapper必须是在本地环境下!!! 设置Linux的用 ...

  8. mysql语句-DML语句

    DML语句 DML是指对数据库中表记录的操作,主要包括数据的增删改查以及更新,下面依次介绍 首先创建一张表:: 表名:emp 字段:ename varchar(20),hiredate date ,s ...

  9. Android PowerManager电源管理(Android N )

    ./frameworks/base/core/java/android/os/PowerManager.java该类提供给Application访问电源相关接口. 它的内部类WakeLock是定义的唤 ...

  10. MySql获取树型结构的所有子节点

    stackoverflow的解决方案,亲测有效: SELECT * FROM person WHERE department IN (SELECT department_id FROM departm ...