目录
缓存 一、缓存介绍
正如大多数持久层框架一样, 同样提供了一级缓存和二级缓存的支持.
1.一级缓存: 基于 的 本地缓存,其存储作用域为,当 flush 或 close之后,该中的所有 Cache 就将清空。
2. 二级缓存与一级缓存其机制相同,默认也是采用 ,存储,不同在于其存储作用域为 Mapper(),并且可自定义存储源,如 。
3. 对于缓存数据更新机制,当某一个作用域(一级缓存/二级缓存)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。
1.导包:
2一级缓存代码
(String[] args) {
as = Test1.class.().("-config.xml");
= ().build(as);
= .();
= .();
Object obj1 = .("user.",1);
Object obj2 = .("user.",1);
System.out.(obj1);
System.out.(obj2);
//关闭
.close();
.close();
}
运行结果:
3.二级缓存代码
(String[] args) {
as = Test1.class.().("-config.xml");
= ().build(as);
//开启两个不同的
= .();
= .();
//使用二级缓存时,User类必须实现一个接口===> User
Object obj1 = .("user.",1);
.commit();//这个地方一定要提交事务之后二级缓存才会起作用
Object obj2 = .("user.",1);
System.out.(obj1);
System.out.(obj2);
//关闭
.close();
.close();
}
(String[] args) {
as = Test1.class.().("-config.xml");
= ().build(as);
//开启两个不同的
= .();
= .();
//使用二级缓存时,User类必须实现一个接口===> User
Object obj1 = .("user.",1);
.commit();//这个地方一定要提交事务之后二级缓存才会起作用
Object obj2 = .("user.",1);
System.out.(obj1);
System.out.(obj2);
//关闭
.close();
.close();
}
运行结果:
4、二级缓存补充说明
1. 映射语句文件中的所有select语句将会被缓存。
2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。
3. 缓存会使用Least Used(LRUhibernate二级缓存注解,最近最少使用的)算法来收回。
4. 缓存会根据指定的时间间隔来刷新。
5. 缓存会存储1024个对象
cache标签常用属性:
缓存 所有缓存机制详解
提供的一级缓存
是一个线程对应一个,一个线程可以看成一个用户。也就是说级缓存(一级缓存)只能给一个线程用,别的线程用不了,一级缓存就是和线程绑定了。
一级缓存生命周期很短,和生命周期一样,一级缓存也称级的缓存或事务级缓存。如果tb事务提交或回滚了,我们称就关闭了,生命周期结束了。
缓存和连接池的区别:缓 存和池都是放在内存里,实现是一样的,都是为了提高性能的。但有细微的差别,池是重量级的,里面的数据是一样的,比如一个池里放100个 连接对象,这个100个都是一样的。缓存里的数据,每个都不一样。比如读取100条数据库记录放到缓存里,这100条记录都不一样。
1.导包
2.一级缓存代码
(String[] args) {
cfg = ();
= cfg.(".cfg.xml").();
= .();
User user = (User).get(User.class, 1);
//第二次查询第一次相同的数据,第二次不会发出sql语句查询数据库,而是到缓存里取数据。
User user2 = (User).get(User.class, 1);
System.out.(user);
System.out.(user2);
//关闭释放一级缓存
.close();
.close();
}
运行结果:
3.二级缓存代码
(String[] args) {
cfg = ();
= cfg.(".cfg.xml").();
= .();
= .();
User user1 =(User).load(User.class, 1);
User user2 =(User) .load(User.class, 1);
System.out.(user1.());
System.out.(user2.());
//关闭 释放二级缓存
.close();
.close();
.close();
}
注:
运行结果:
可见,二级缓存是起作用了的。用get测试是同样的结果。
4.三级缓存代码
(String[] args) {
cfg = ();
= cfg.(".cfg.xml").();
= .();
Query query1 = .("FROM User");
query1.(true);
//List list1 = query1.list();
= query1.();
Query query2 = .("FROM User");
query2.(true);
//List list2 = query2.list();
= query2.();
System.out.();
System.out.();
//关闭 释放三级缓存
.close();
.close();
}
运行结果:
5.一级缓存 二级缓存 三级缓存 之间的比较
一级缓存(级的缓存):在一个中load同一个对象2次,load时,首先在缓存中查找对象,如果没找到就到数据库中去load。因此,在同一个中load一个对象2次,只会发出一条sql语句。而在2个中load同一个对象则会发送2次sql语句。
二级缓存(的公用缓存,级别的缓存,jvm级缓存):支持多种二级缓存,提供了一个,用于测试,不建议运用与产品中。
二级缓存适合放什么对象呢?
①经常被访问(这个对象经常被访问,如果每次都到数据库去取hibernate二级缓存注解,会降低效率)
②改动不大(这个对象改动不大,如果改动较大,就可能造成缓存数据跟数据库中的数据不一致)
三级缓存(查询缓存):如果要使Query使用二级缓存,则需要打开查询缓存。事实上,三级缓存是基于二级缓存的,如:list(集合),默认情况,它只会往二级缓存中存放数据,查找时不会搜索二级缓存,这是因为查询条件会随时变化。有一种情况就是2次查询的条件是一样的,这是要想使用二级缓存,就必须打开查询缓存,打开方式如:
true
然后加上:(true)
缓存算法有:
LRU(Least Used):这种算法是在每个对象中维护一个访问的时间变量,每次访问后,时间都会更新,当新的对象需要存放到缓存时,替换那个按时间排序最后的对象。
LFU(Least Used):这种算法是每个对象记录了对象访问的次数(即命中率),当新的对象需要存放到缓存时,替换那个访问次数最少的对象。
FIFO(First In First Out):这种算法是将缓存中的对象存放成一个数组,当新的对象需要存放到内存中是,替换最先存放到缓存的对象。
使用时通常在缓存配置文件中加入:olicy="LRU"。
list和存放的不同之处:
①List:直接取出所有的记录将其封装成对象放到集合中。
:先取出所有记录的id(主键),当需要用到对应的id的记录时,再根据id发sql语句。②list不会主动利用级的缓存,因此list遍历时每次会到数据库中取数据。
会利用的缓存,每次会到缓存中找,如果缓存中没有,再到数据库中取数据。
③默认使用二级缓存
list默认往二级缓存存数据,但是查询时不使用二级缓存。
本文共 1402 个字数,平均阅读时长 ≈ 4分钟