zoukankan      html  css  js  c++  java
  • 【Hibernate】一级、二级缓冲

    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的常见特性,闲来无事,喜欢写着玩,大家随便看,有问题及时探讨。

  • 相关阅读:
    android29
    android28
    android27
    android26
    Dynamics CRM2011 MspInstallAction failed when installing an Update Rollup
    Dynamics CRM Import Solution Attribute Display Name description is null or empty
    The service cannot be activated because it does not support ASP.NET compatibility
    IIS部署WCF报 无法读取配置节“protocolMapping”,因为它缺少节声明
    Unable to access the IIS metabase.You do not have sufficient privilege
    LM算法与非线性最小二乘问题
  • 原文地址:https://www.cnblogs.com/dyllove98/p/4121570.html
Copyright © 2011-2022 走看看