hibernate一级缓存和二级缓存 三级缓存,hibernate的二级缓存,Hibernate一级缓存和二级缓存详解

hibernate一级缓存和二级缓存 三级缓存,hibernate的二级缓存,Hibernate一级缓存和二级缓存详解

今天,边肖将与您分享Hibernate一级缓存和二级缓存的详细说明。边肖觉得内容挺好的,现在分享给大家,很有参考价值。有需要的朋友就跟着边肖去看看吧。

一、一级缓存二级缓存的概念解释

(1)一级缓存是会话级缓存。当会话进行查询操作时,它会将该操作的结果放在一级缓存中。如果这个会话(必须是同一个会话)短时间内再次做同样的操作,那么hibernate直接从一级缓存中取,而不是连接数据库取数据;

(2)二级缓存是sessionFactory级别的缓存。顾名思义,它在查询时将查询结果缓存到二级缓存中。如果同一个sessionFactory创建的会话执行相同的操作,hibernate会从二级缓存中获取结果,而不是连接数据库;

(3)Hibernate提供了两级缓存。第一级缓存是会话级缓存,属于事务范围。这一级别的缓存由hibernate管理,通常不需要干预;第二级缓存是会话工厂级缓存,这是一个进程范围或集群范围的缓存。这种级别的缓存可以配置和更改,并且可以动态加载和卸载。Hibernate还提供了查询结果的查询缓存,依赖于二级缓存;

二、一级缓存和二级缓存的比较

(1)一级缓存和二级缓存以相互关联的持久对象的形式存储数据。批量数据缓存事务的作用域,每个事务都有单独的一级缓存进程作用域或集群作用域,缓存由同一进程或集群作用域内的所有事务共享。并发访问策略,因为每个事务都有单独的一级缓存,不会造成并发问题。不需要提供并发访问策略。因为多个事务将同时访问L2缓存中的相同数据,所以必须提供适当的并发访问策略,以确保特定事务隔离级别的数据过期策略不提供数据过期策略。

(2)一级缓存中的对象永远不会过期,除非应用程序显式清除缓存或清除特定对象。必须提供数据过期策略,例如基于内存的缓存中的最大对象数、对象在缓存中停留的最长时间以及对象在缓存中停留的最长空闲时间。物理存储介质内存和硬盘。

(3)对象的批量数据首先存储在基于内存的缓存中。当内存中的对象数量达到数据过期策略中指定的上限时,剩余的对象将被写入基于硬盘的缓存中。

(4)缓存的软件实现包括Hibernate的Session中第三方提供的缓存的实现,而Hibernate只提供一个CacheProvider。用于将特定的缓存插件集成到Hibernate中。

(5)如何启用缓存。只要应用程序通过Session接口对数据库数据进行保存、更新、删除、加载、查询等操作,Hibernate就会启用一级缓存,将数据库中的数据以对象的形式复制到缓存中。对于批量更新和批量删除操作,如果不想启用一级缓存,可以绕过Hibernate API,直接通过JDBC API进行指向操作。

(6)用户可以在单个类或单组类的粒度上配置二级缓存。如果一个类的实例被频繁读取但很少修改,可以考虑使用二级缓存。

(7)只有当二级缓存是为类或集合配置的,Hibernate才会在运行时将其实例添加到二级缓存中。用户如何管理缓存:一级缓存的物理介质是内存。由于有限的内存容量,必须通过适当的检索策略和检索方法来限制加载对象的数量。Session的evit()方法可以显式清空缓存中的特定对象,但不建议使用此方法。二级缓存的物理介质可以是内存和硬盘,所以二级缓存可以存储大量的数据。数据过期策略的maxElementsInMemory属性的值可以控制内存中的对象数量。

(8)L2缓存的管理主要包括两个方面:选择需要L2缓存的持久类,设置合适的并发访问策略;选择缓存适配器并设置适当的数据过期策略。

三、 一级缓存的管理

(1)当应用程序调用Session的save()、update()、savaeOrUpdate()、get()或load()方法,调用查询接口的list()、iterate()或filter()方法时,如果Session缓存中不存在对应的对象,Hibernate会将其添加到一级缓存中。清理缓存时,Hibernate会根据缓存中对象的状态变化同步更新数据库。Session为应用程序提供了两种管理缓存的方法:evict(Object obj):从缓存中清除参数指定的持久对象。Clear():清除缓存中的所有持久对象。

(2)save、update、saveOrupdate、load、list、iterate、lock将数据存储在一级缓存中;

保存案例:

//添加学生

学生学生=新生();

Student.setName('晓东');

s.save(学生);//放入一级缓存

//我马上检查一下

Student 2=(Student)s . get(Student . class,Student . getid());//选择

System.out.println('你刚加入的学生名字是' stu 2 . getname());

(3)什么操作会从一级缓存取数据:get、load、list?

Get/load将首先从一级缓存中获取。如果没有,会有不同的操作【get会立即向数据库发送请求,而Load会返回一个代理对象,直到用户实际使用数据后才会向数据库发送请求;

//查询45号学生。

学生stu=(学生)s.get(学生.类,45);

system . out . println(' | | | | | | | | | | | | | ');

字符串hql=' from Student where id=45

学生stu2=(学生)s.createQuery(hql)。uniqueResult();

system . out . println(stu 2 . getname());

从上面的案例可以看出,query.list()query.uniueResut()不会缓存第一级起的数据!但是,query.list或query.uniqueRestu()会将数据放入一级缓存。

注意:

一级缓存不需要配置就可以使用,它没有保护机制,所以我们程序员要考虑这个问题。我们可以使用evict或clear来清除会话缓存中的对象。evict是清除一个对象,clear是清除所有的会话缓存对象。

会话缓存中对象的生命周期将在会话关闭时自动销毁。

我们用HashMap模拟一个会话缓存来深化缓存。

四、Hibernate二级缓存的管理

1.Hibernate L2缓存策略的一般流程如下:

1)在进行条件查询时,一定要发出类似select * from table_name where …(选择所有字段)这样的SQL语句来查询数据库,一次得到所有的数据对象。

2)根据ID将获得的所有数据对象放入二级缓存。

Hibernate根据ID访问数据对象时,先从会话一级缓存中检查;否,如果配置了L2缓存,请从L2缓存中检查;如果找不到,那么查询数据库,根据ID将结果放入缓存。

4)删除、更新和添加数据时,同时更新缓存。Hibernate L2缓存策略是一种针对ID查询的缓存策略,但是对条件查询没有影响。为此,Hibernate为条件查询提供了QueryCache。

5) L2缓存对象可以存储在内存或磁盘中。

2.哪种数据适合存储在L2缓存中?

1)很少修改的数据

2)不是很重要的数据,允许偶尔并发数据。

3)不会被并发访问的数据

4)参考数据是指供参考的常量数据。它的实例是有限的,它的实例会被许多其他类引用,它的实例很少或从不修改。

3.不适合存储在二级缓存中的数据?

1)频繁修改的数据

2)财务数据的并发是绝对不允许的。

3)与其他应用程序共享的数据。

4.常用的缓存插件Hibernater L2缓存是一个插件。以下是几种常用的缓存插件:

EhCache:可以作为进程级缓存,存储数据的物理介质可以是内存,也可以是硬盘,为Hibernate的查询缓存提供支持。

OSCache:可以作为进程级缓存,存储数据的物理介质可以是内存,也可以是硬盘。它提供了丰富的缓存数据过期策略,并支持Hibernate的查询缓存。

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

JBossCache:可以作为集群范围的缓存,支持事务并发访问策略,支持Hibernate的查询缓存。

5.配置Hibernate L2缓存的主要步骤:

1)选择需要使用L2缓存的持久类,并设置其命名缓存的并发访问策略。这是值得认真考虑的步骤。

2)选择适当的缓存插件,然后编辑插件的配置文件。

属性名='hbm2ddl.auto'update/property

!-启动L2缓存-

property name=' cache . use _ second _ level _ cache ' true/property

!-指定要使用哪种类型的L2缓存-

property name=' cache . provider _ class ' org . hibernate . cache . oscacheprovider/property

映射资源=' com/HSP/domain/department . hbm . XML '/

映射资源=' com/HSP/domain/student . hbm . XML '/

!-指定哪个域启用L2缓存。

解释特殊的L2缓存策略:

1.只读

2.读写

3.非严格读写

4.跨国公司

-

class-cache class=' com . HSP . domain . student '用法='read-write'/

3)你可以把oscache.properties文件放在src目录下,这样你就可以指定放在L2缓存中的对象容量的大小。默认值为1000。

6.使用L2缓存:

//TODO自动生成的方法存根

//通过获取会话让hibernate框架运行(config- load hibernate.cfg.xml)

会话s=null

事务tx=null

尝试{

//我们用基本模板来解释。

s=hibernate util . opensession();

tx=s . begin transaction();

//查询45号学生。

Student 1=(Student)s . get(Student . class,45);//45级1级缓存

system . out . println(stu 1 . getname());

tx . commit();

} catch(异常e) {

e . printstacktrace();

如果(tx!=null){

tx . roll back();

}

}最后{

如果(s!=null s.isOpen()){

s . close();

}

}

system . out . println(' * * * * * * * * * * * * * * * * * * * * * * * * * * * * * ');

尝试{

//我们用基本模板来解释。

s=hibernate util . opensession();

tx=s . begin transaction();

//查询45号学生。

Student 1=(Student)s . get(Student . class,45);

system . out . println(stu 1 . getname());

学生stu3=(学生)s.get(学生.类,46);

system . out . println(stu 3 . getname());

tx . commit();

} catch(异常e) {

e . printstacktrace();

如果(tx!=null){

tx . roll back();

}

}最后{

如果(s!=null s.isOpen()){

s . close();

}

}

//完成一个统计,统计信息在Sessfactory。

//SessionFactory对象。

statistics statistics=hibernate util . getsession factory()。get statistics();

System.out.println(统计);

system . out . println(' put in ' statistics . getsecondlevelcacheputcount());

system . out . println(' hit ' statistics . getsecondlevelcachehitcount());

system . out . println(' miss ' statistics . getsecondlevelcachemiscount());

配置完L2缓存后,请注意可以通过统计来检查自己的配置命中率高不高。

总结

这就是本文的全部内容。希望这篇文章的内容对你的学习或工作有一定的参考价值。谢谢你的支持。如果你想了解更多,请查看下面的相关链接。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: