Hibernate性能优化之二级缓存

基本原理:

我自己的理解就是缓存在内存中的存在方式可以简单的看成一个Map,

通过key在缓存里面找value。对于对象来说,这个键就是id,而值就是

对象实例,而对与query查询结果的缓存,键是query中使用的sql或hql语句

在hibernate框架中使用用二级缓存,当查询的时候,就会根据这个键去找

现在缓存中找,如果没有,就再到数据库里找。

适用场合:

并不是说所有的场合使用了缓存,就一定能够提高性能,那么什么时候适合用,

用什么方式的缓存,这都需要慎重(需要抽出时间详细的学习了解),一般的是在数

据没有第三方修改,数据大小在数据大小在可接收范围之内,数据更新频率低,非

关键数据(不是财务数据等)满足这些条件的时候。

我使用二级缓存的环境背景

我公司是运营的是3G城市快讯项目,主要是展现出数据,让用户去浏览,基本上完

全符合二级缓存的适用场合,所以在前台数据展现时大量使用了二级缓存技术,很明显

的加快了响应速度,提高了的网站的性能。

使用hibernate二级缓存一般都是借助于第三方缓存框架,目前有多种方式可供选择,

我公司项目采用的是OSCache的方式,配置了读写型(缓存有多种,分只读型,读写性等等)

缓存,对此,我在学习,工作的工程中,感触颇深,以下是我的一些总结:

1.

借助OsCache实现二级缓存,只需要在hibernate的基础之上添加一个oscache-2.4.1.jar包

需要在hibernate.cfg.xml中添加

<propertyname="hibernate.cache.use_query_cache">true</property>

<propertyname="hibernate.cache.use_second_level_cache">

true

</property>

<propertyname="hibernate.cache.provider_class">

org.hibernate.cache.OSCacheProvider

</property>

2.

需要在.hbm.xml文件中加上<cacheusage="read-write"/>,

这主要是对对象通过id(getload)查询时使二级缓存生效

如下

<classname="com.caituo.waptown.bean.Content"table="WAPTOWN_CONTENT">

<cacheusage="read-write"/>--配置缓存方式是不严格读写型缓存

3.在ssh中

调用get()方法将对象加载到内存中,如果配置了二级缓存,那么这个对像将会在缓存中,

调用update()方法更改后,将会更改内存中缓存的这个对象,同时修改数据库

而如果,你进行了二级缓存,在项目运行期间修改了数据库中的数据,缓存中的数据将还是原来的,不能显

示出你的最新修改,除非手动清空缓存中的对象。

调用以下方法可清空所有的缓存对象,以及query查询的缓存

publicvoidevictSecondLevelCache(){

SessionFactorysf=this.getSessionFactory();

//清空所有对象

Map<String,CollectionMetadata>roleMap=sf.getAllCollectionMetadata();

for(StringroleName:roleMap.keySet()){

sf.evictCollection(roleName);

}

Map<String,ClassMetadata>entityMap=sf.getAllClassMetadata();

for(StringentityName:entityMap.keySet()){

sf.evictEntity(entityName);

}

//清空query查询的结果,但是作为对象被缓存的将不被清空

sf.evictQueries();

}

调用以下语句可清空二级缓存中的某单个对象

this.getSessionFactory().evict(Content.class,contentid);

这可以单独做一个页面,叫做“刷新缓存”,专门用来在直接通过sql更改数据库后同步数据库与缓存中的

数据。

4.hibernate的二级缓存是建立在SessionFactory级别的

配置了SessionFactory后,所有的hibernate的session都将共用缓存的数据

当单独使用hibernate的时候,想要使用二级缓存,则应将SessionFactory声明为静态的,

eg:

privatestaticConfigurationconfig=newConfiguration().configure();

privatestaticSessionFactoryfactory=config.buildSessionFactory();

如果用了spring,则不用做了

用了spring的项目一旦启动,自始至终就是只有一个SessionFactory对象了。

5.当使用query查询并配置二级缓存的时候两种sql语句的不同

A.

Stringhql="selectnewmap(user.userIdasuserid,user.userNameasusername,userAddressas

useraddress)fromUserTbluser";

B.

Stringhql="fromUserTbl";

上述中的A法查询后只缓存sql-查询结果这么一个键值对的形式,当你再通过id去查询的时候,仍然会去查询数据库。

而使用B法查询后,不仅缓存sql-查询结果这么一个键值对,而且缓存所有已经查询出的(id-对象)键

值对,也就是在配置了二级缓存的前提下通过的Stringhql="fromUserTbl"查询后,你再通过id去查某个

对象(限于get(),load()方法),也不会再去查询数据库了。

6.使用OsCache缓存还应有一个配置文件

oscache.properties默认路径为:

在这个文件中有一些重要的参数,譬如,配置你的系统的最大缓存数、缓存过期时间等等

7.另外,OsCache是一个独立的缓存框架,它可以在只有jsp-servlet的程序中独立使用

为了更清晰的了解掌握并熟练运用,我也专门做了示例,上传在我的blog

http://bingyingao.download.csdn.net/

相关推荐