Hibernate性能优化 --- 缓存管理

Hibernate性能优化 --- 缓存管理

一 hibernate内部缓存的分析

1、一级缓存 --- Session级别的缓存概念

Session级别的缓存由Hibernate自动管理的,一般情况下无需进行干预,当应用程序调用Session的CURD方法以及调用查询接口的list等等方法时,如果缓存中还不存在响应的对象,Hibernate就会把该对象加入到Session缓存中。当Hibernate清理缓存时,Hibernate会根据缓存中的状态变化来同步数据库中的数据状态,在Session关闭时,会清空Session缓存中的所有对象。

2.测试缓存的存在

public static User getUser(int id) {

Session session = null;

try {

session = HibernateUtil.getSession();

//第一次查询的时候从数据库中查询,并且把数据放到缓存中

User user = (User) session.get(User.class, id);

System.out.println("----------------");

//在第二次查询的时候没有输出查询的语句,是因为是从缓存中查的而不是数据库

user = (User) session.get(User.class, id);

} finally {

if (session != null) {

session.close();

}

}

}

注:输出的结果只有一条select语句,原因就是第一次查询的时候从数据库中查询,并且把数据放到缓存中,第二次查询的时候没有输出查询的语句,是因为是从缓存中查的而不是数据库

3.测缓存的生命周期

public static User getUser(int id) {

Session session = null;

try {

session = HibernateUtil.getSession();

//第一次查询的时候从数据库中查询,并且把数据放到缓存中

User user = (User) session.get(User.class, id);

} finally {

if (session != null) {

session.close();

}

}

try {

session = HibernateUtil.getSession();

//第一次查询的时候从数据库中查询,并且把数据放到缓存中

User user = (User) session.get(User.class, id);

return user;

} finally {

if (session != null) {

session.close();

}

}

注:以上的代码结果是有两条select语句,是因为在session关闭之后一级缓存也就关闭了,当再次开启的获取连接的时候,又是一次查询

4.缓存中是设计的三个操作:

(1)把数据放入到缓存的操作,当再调用save upate saveOrupdate load get list.iterate lock这些方法都可以将数据放到一级缓存中,为了优化查询,但是一级缓存不能控制缓存的数据,所以要注意大批量操作

(2)从缓存中获取数据 查询的时候

get() load()方法先去缓存中查询数据,如果缓冲中有对象直接返回该对象,如果没有,就去数据库中查询数据

Query接口的查询(list方法)不从 缓存中提取数据,直接访问的是数据库,但是查询的数据会存放到缓存中

Criteria不从缓存中提取数据

(3)删除缓存中无效的数据

5.清除一级缓存

session.evict(user);//清除缓存中指定的对象

session.clear();//清除一级缓存中的所有对象

但是绝大多数情况下不需要人为的清理,Hibernate会自行处理

6.一级缓存的缺陷

(1)一级缓存没有保护,不能控制缓存的数据,所以要注意在放入缓存中数据的时候要注意,如果过大,可人为的清理缓存

(2)共享的范围太小,不能实现共享。因为一级缓存是session的缓存,session的存在时间是一次会话。

2.二级缓存 --- SessionFactory级别的缓存

1.配置二级缓存 要在hibernate.cfg.xml中配置,主要告诉hibernate第三方的缓存的提供者是谁,

(1)二级缓存的打开 hibernate.cache.use_second_level_cache

<property name="hibernate.cache.use_second_level_cache">true</property>

决定要不要打开二级缓存,这个属性的默认值为真,该属性不配置也可以

(2)二级缓存的提供者 hibernate.cache.provider_class

<property name="hibernate.cache.provider_class">org.hibernate.cache.OSCacheProvider</property>

Cache的提供者是org.hibernate.cache.OSCacheProv,并且将oscache】需要的jar包构建到lib下

需要将oscache.properties拷贝到classPath路径下,也就是src下,文件名字和路径不可以该

(3)告诉hibernate哪些类是需要放入二级缓存的 <class-cach>标签

方法一:

<class-cache usage="read-only" class="com.hbsi.domain.User"/>

包名必须是完全限定名

(3).1缓存的使用策略

Usage:read-only 只读的缓存,效率是最高的,但是有一个限制,当缓存中的数据被更新的话就会抛异常

read-write:可读取的缓存,可以并发的修改数据,但是会付出代价的,效率会受到影响

nostrict-read-writer 不严格的缓存,不对数据进行加锁,效率高点

transactional 事务型的缓存,一般的缓存框架不支持

方法二:

在类的映射文件中告诉hibernate,在<class>类的标签中放入

<cache usage="read-only"/>

2.测试二级缓存

实例分析:

public static User getUser(int id) {

Session session = null;

try {

session = HibernateUtil.getSession();

User user = (User) session.get(User.class, id);//数据库中查找

user = (User) session.load(User.class, id);//一级缓存查询

} finally {

if (session != null) {

session.close();

}

}

try {

session = HibernateUtil.getSession();

User user = (User) session.get(User.class, id);

//二级缓存中查: 先从一级缓存中查找,再从二级缓存中查找

return user;

} finally {

if (session != null) {

session.close();

}

}

}

注:

执行结果为输出一条select语句,因为是从二级缓存后中查找的

当清除缓存的时候,也是输出一条语句,因为清除的缓存只是清除一级缓存的

3.得到缓存中的命中

命中:如果查询的数据是从二级缓存中查找出来的话是命中

miss错过:如果查询的数据是从数据库中查询的

在Statistics st = SessionFactory.getStatistics()得到缓存的统计信息

表示在工作的工程中,可以产生统计信息

<property name="hibernate.generate_statistics">true</property>

通过调用

Statistics

statistics = HibernateUtil.getSessionFactory().getStatistics();

得到统计的所有信息,为:

Statistics[start time=1324006126656,sessions opened=3,sessions closed=3,transactions=1,successful transactions=1,optimistic lock failures=0,flushes=1,connections obtained=2,statements prepared=2,statements closed=2,second level cache puts=1,second level cache hits=1,second level cache misses=1,entities loaded=1,entities updated=0,entities inserted=1,entities deleted=0,entities fetched=0,collections loaded=0,collections updated=0,collections removed=0,collections recreated=0,collections fetched=0,queries executed to database=0,query cache puts=0,query cache hits=0,query cache misses=0,max query time=0]

注:

opens = 3 是session被打开了三次

transactions成功的事务数

second level cache puts=1 二级缓存放入的次数

second level cache hits=1 二级缓存命中的次数

second level cache misses=1 二级缓存错过的次数

放入:

save可以把对象放入二级缓存,但是主键不是native,如果不是用native,就可以放入二级缓存。

命中:命中是从二级缓存中去吃来的

错过:是在从二级缓存中查询的时候没有存在的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值