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. bdb log file 预设长度的性能优化

    看代码随手记:log_put.c, __log_write() /* * If we're writing the first block in a log file on a filesystem ...

  2. (期望)A Dangerous Maze(Light OJ 1027)

    http://www.lightoj.com/volume_showproblem.php?problem=1027 You are in a maze; seeing n doors in fron ...

  3. php面试题及答案收藏(转)

    php面试题及答案收藏(这套试题是在网上看到的,不知作者是谁) 基础题 1.表单中 get与post提交方法的区别? 答:get是发送请求HTTP协议通过url参数传递进行接收,而post是实体数据, ...

  4. [CSDN转载]致C语言初学者—指针注意项

    在论坛里经常见到一些新人对指针提出一些问题,作为一个经历过许多错误后的新手,我想把自己的经历说出来,避免让后来人继续这样的错误.    在讲解指针之前,需要理解一下内存空间.内存是随机存取器,计算机上 ...

  5. android数据库SQLite的设计模式

    Dao设计模式可能是使用最多的数据库的设计模式其基本思路是将数据库操作的代码 与设计代码分离以便于维护和升级.具体的实现方法是使用包,然后在设计代码中调 用数据库的操作代码,dao设计模式需要创建5个 ...

  6. DBCC 命令2

    状态查询:收集和显示各类信息,状态检查. 如cachestats.pss.sqlmgrstats.memorystatus.proccache.freeproccache.freesystemcach ...

  7. 《你必须知道的.NET》读书笔记:从Hello World认识IL

    通用的语言基础是.NET运行的基础,当我们对程序运行的结果有异议的时候,如何透过本质看表面,需要我们从底层来入手探索,这时候,IL便是我们必须知道的基础. 一.IL基础概念 1.1 什么是IL? IL ...

  8. 从C#垃圾回收(GC)机制中挖掘性能优化方案

    GC,Garbage Collect,中文意思就是垃圾回收,指的是系统中的内存的分配和回收管理.其对系统性能的影响是不可小觑的.今天就来说一下关于GC优化的东西,这里并不着重说概念和理论,主要说一些实 ...

  9. 【面试必备】javascript的原型和继承

    原型.闭包.作用域等知识可以说是js中面试必考的东西,通过你理解的深度也就能衡量出你基本功是否扎实.今天来复习一下javascript的原型和继承,虽说是老生常谈的话题,但对于这些知识,自己亲手写一遍 ...

  10. 赴美工作常识(Part 3 - 英语)

    在<Part 2 - 申请>的评论中有人问英语要达到何种水平,以及如何提高.其实英语也不是我的强项,只是刚刚好做到能够沟通而已.由于我在知乎上回到过一个类似问题,我就基于那个答案简单说一下 ...