Hibernate缓冲按级别共分为两种,一级缓冲(Session)和二级缓冲(SessionFactory),有的也说是三种,还有一种是查询缓冲,当然,查询缓冲是依托于二级缓冲。

ok,什么是缓冲?

在内存里开辟一块空间把本来应该存在硬盘里面的数据,存在这个空间里面,将来,需要这块数据的时候直接在内存中获取。这个就可以简单理解为缓冲。

一级缓冲

什么是一级缓冲,一级缓冲是Hibernate默认的,不用管它。

比如下面这段代码,

1
2
3
4
5
6
7
8
9
10
11
@Test
    publicvoid findTestyijihuanchong(){
       Session s=sessionFactory.openSession();
       s.beginTransaction();
       Person person=(Person)s.load(Person.class1);
       System.out.println(person.getName());
       //因为Session存在缓冲,所以这个查询直接在session中取
       Person person2=(Person)s.load(Person.class1);
       System.out.println(person2.getName());
       s.getTransaction().commit();
    }

我们发现,只会发出一条sql语句,那么这个就是Hibernate自带的一级缓冲。

那比如下面这种情况,新开的Session呢?在系统中,多线程并发的时候,肯定不止产生一个Session,所以在优化性能时,一级缓冲往往满足不了需求,那么就有了二级缓冲

比如下面这段代码,显然发出的是两条SQL语句。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
    publicvoidfindTestyijihuanchong(){
        Sessions=sessionFactory.openSession();
        s.beginTransaction();
        Personperson=(Person)s.load(Person.class1);
        System.out.println(person.getName());
        s.getTransaction().commit();
        s.close();
         
        Sessions2=sessionFactory.openSession();
        s2.beginTransaction();
        Personperson2=(Person)s2.load(Person.class1);
        System.out.println(person2.getName());
        s2.getTransaction().commit();
        s2.close();
    }

二级缓冲

什么是二级缓冲?二级缓冲也可以理解为SessionFactory级别的缓冲,SessionFactory是生产Session的工厂,那么我们可不可以这么理解,Session关联一个指向数据库的结果集,那么下次我在发SQL的时候,我发现,SessionFactory里面已经有了一个指向这个结果集的语句,那么我是不是可以直接使用了!

具体来说,二级缓冲并不是由Hibernate来提供,是由第三方提供的缓冲插件,通常有以下几种第三方缓冲插件:

EhCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。

OSCache:可作为进程范围的缓存,存放数据的物理介质可以是内存或硬盘,提供了丰富的缓存数据过期策略,对Hibernate的查询缓存提供了支持。

SwarmCache:可作为群集范围内的缓存,但不支持Hibernate的查询缓存。

JBossCache:可作为群集范围内的缓存,支持事务型并发访问策略,对Hibernate的查询缓存提供了支持。

那么,哪些数据适合放在二级缓冲中,理解二级缓冲特性之后,我们知道,

1、经常被查询的数据,这样的数据需要频繁访问数据库,肯定是非常适合放在缓冲

2、很少并发的数据,什么意思呢?打个比方,一个查询,一个修改,这样很可能会造成一种脏读,或者是幻读。意思就是你的数据库的数据可能被修改了,但是设置二级缓冲还没有及时更新

3、重要的数据,这个不多说

总之,放在二级缓冲中的数据,一般都是不重要的,不经常修改的数据。比如说,菜单,比如说权限。这些都是非常适合放在二级缓冲中,比如说财务数据,工资数据等,这些不建议放在二级缓冲中

我们上面讲了二级缓冲是第三方提供的那么显然我们需要配置,

首先我们需要在我们的hibernate.cfg.xml中开启我们的二级缓冲,当然也可能是properties文件中配置

1
2
3
4
5
6
<!-- 开启缓冲 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!--指定是哪个二级缓冲-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
<!-- 使用查询二级缓冲 -->
<propertyname="hibernate.cache.use_query_cache">true</property>

第二步,我们指定是哪个实体类需要二级缓冲

Annotations配置

1
2
3
@Entity
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
@Table(name="p_person")

XML配置

1
2
3
<class name="Person" table="t_person">
        <cache usage="read-write"/>
        <id name="id">

记住XML配置一定是id之前,class之内

还必须有ehcache.xml文件,这个文件有兴趣大家可以在网上自己看一下,这里我就不讲解,里面的内容了

配置完之后,我们直接看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Test
    publicvoid findTesterjihuanchong(){
        Sessions=sessionFactory.openSession();
        s.beginTransaction();
        Personperson=(Person)s.load(Person.class, 1);
        System.out.println(person.getName());
        s.getTransaction().commit();
        s.close();
         
        Sessions2=sessionFactory.openSession();
        s2.beginTransaction();
        Personperson2=(Person)s2.load(Person.class, 1);
        System.out.println(person2.getName());
        s2.getTransaction().commit();
        s2.close();
    }

这个时候,我们再看,肯定又是只发送一条SQL语句了。

查询缓冲

什么是查询查询缓冲。顾明思议它是查询的时候产生的缓冲,那我们前面讲到了二级缓冲,查询缓冲和二级缓冲是什么关系?首先查询缓冲是依赖于二级缓冲的,查询缓冲一般设置在list()方法中,查询缓冲是重复查询使用的缓冲,如果你两个查询不一样,这个存在的缓冲是不起作用的。需要注意的是list()查询缓冲必须要告诉hibernate,使用查询缓冲,查询缓冲才会生效。

setCacheable(true)

ok,看代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
    publicvoid findTestList(){
        Sessions=sessionFactory.getCurrentSession();
        s.beginTransaction();
        List<Person>persons=s.createQuery("fromPerson").setCacheable(true).list();
        List<Person>person1=s.createQuery("fromPerson").setCacheable(true).list();
        for(Person person:persons){
            System.out.println(person.getName()+"----"+person.getId());
        }
        for(Person person:person1){
            System.out.println(person.getName()+"----"+person.getId());
        }
        s.getTransaction().commit();
    }

到这里,我们基本上做完了Hibernate缓冲,但是缓冲怎么配置,怎么使用,要根据实际的项目情况而定,并不是说,配置了二级缓冲一定会提高系统性能。同时,高级的可能也牵涉到缓冲算法等问题。当然在项目中多犯几次错误,自然就会使用Hibenrate缓冲了!

下篇博文写悲观锁和乐观锁,写完之后,我会写一篇怎么模仿开发一套属于我们自己ORM框架,基本上就写完了Hibenrate的常见特性,闲来无事,喜欢写着玩,大家随便看,有问题及时探讨。

【Hibernate】一级、二级缓冲的更多相关文章

  1. Hibernate 一级二级缓存

    1.一级缓存与session关联,session关闭时,缓存数据消失: 2.一级缓存无法自我控制缓存的数量,需考虑缓存溢出: 3.二级缓存与sessionFactory关联,当sessionFacto ...

  2. 关于hibernate一级缓冲和二级缓冲

    关于一级缓冲和二级缓冲的内容,在面试的时候被问起来了,回答的不是很满意,所以有专门找了些有关这方面的文章加以理解 出自:http://blog.csdn.net/zdp072/article/deta ...

  3. Hibernate一级缓冲

    Hibernate的一级缓冲 什么是缓冲 缓冲概念: 数据存在数据库中,数据库本身就是一个文件系统,使用流的方式操作文件,但是文件中有很多的内容,用流的操作得效率就低. 解决办法: 把数据存在内存中, ...

  4. Hibernate的一级二级缓存机制配置与测试

    特别感谢http://www.cnblogs.com/xiaoluo501395377/p/3377604.html 在本篇随笔里将会分析一下hibernate的缓存机制,包括一级缓存(session ...

  5. Hibernate一级缓存与二级缓存的区别

    一级缓存: 就是Session级别的缓存.一个Session做了一个查询操作,它会把这个操作的结果放在一级缓存中. 如果短时间内这个session(一定要同一个session)又做了同一个操作,那么h ...

  6. Hibernate一级缓存、二级缓存

    缓存就是把以前从数据库中查询出来和使用过的对象保存在内存中,准确说就是一个数据结构中,这个数据结构通常是或类似HashMap,当以后要使用某个对象时,先查询缓存中是否有这个对象,如果有则使用缓存中的对 ...

  7. Hibernate一级缓存和二级缓存深度比较

    1.什么是缓存 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能.缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据, ...

  8. hibernate一级缓存和二级缓存的区别

    http://blog.csdn.net/defonds/article/details/2308972 缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了 ...

  9. 说说自己对hibernate一级、二级、查询、缓存的理解。

    说说自己对hibernate一级.二级.查询.缓存的理解. 2016-03-14 21:36 421人阅读 评论(0) 收藏 举报  分类: web开发(19)  版权声明:本文为博主原创文章,未经博 ...

随机推荐

  1. middleware - bodyparser

    express4之前,bodyparser是express下的一个对象. express4把bodyparser分离出来. 本文中的实例基于以下的这个请求 $.ajax({ url: '/save', ...

  2. 关于PDV的那些事

    数据集中的数据来源分为两种: 一.来自于另一个数据集: 二.来自于外部数据源(本文细说此来源): 无论是哪种来源,在它们成为目标数据集中的观测行(官方叫它observation)之前都要进入PDV,先 ...

  3. How to create Web Deployment Package and install the package

    Create Web Deployment Package To configure settings on the Connection tab In the Publish method drop ...

  4. ActionBar的使用

    ActionBar的使用很普遍,可以充当工具栏使用.本文介绍如何使用ActionBar. 1.ActionBar一般包含有多个工具按钮.所以,需要新建一个xml文件来存放ActionBar中的内容.在 ...

  5. Largest Rectangle in a Histogram(DP)

    Largest Rectangle in a Histogram Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K ...

  6. CentOS7使用阿里云镜像安装Mongodb

    一.概述 近日要在新的CentOS系统上安装MongoDB,某度结果后直接从Mongo官网直接获得3.2版本的下载链接,结果在下载时发觉速度慢的可怜.迫于无奈,只能找国内的镜像下载.切换国内的安装源后 ...

  7. jmSlip WEB前端滑屏组件

    基于css3的滑屏组件 demo: http://slip.jm47.com 下载: https://github.com/jiamao/jmSlip 功能清单 区域横滚 整屏竖滚 滚动动画效果 区域 ...

  8. 创建动态WCF服务(无配置文件)

    public class WCFServer { ServiceHost host = null; public WCFServer(string addressurl, string tcpurl, ...

  9. python post

    使用python 提交表单包括图片以及参数信息,详见代码 # -*- coding: utf-8 -*- import MultipartPostHandler, urllib2, cookielib ...

  10. [后端人员耍前端系列]KnockoutJs篇:快速掌握KnockoutJs

    一.引言 之前这个系列文章已经介绍Bootstrap.由于最近项目中,前端是Asp.net MVC + KnockoutJs + Bootstrap来做的.所以我又重新开始写这个系列.今天就让我们来看 ...