1. Session对象的缓存
![内存中Session对象的缓存](https://i-blog.csdnimg.cn/blog_migrate/61b21ee931c2a622111e60b358adf7a7.jpeg)
内存中Session对象的缓存
什么是缓存?
其实就是一块内存空间,将数据源(数据库或者文件)中的数据存放到缓存中.再次获取的时候 ,直接从缓存中获取.可以提升程序的性能!Hibernate 框架提供了两种缓存
- 一级缓存 – 自带的不可卸载的.一级缓存的生命周期与 session 一致. 一级缓存称为session 级别的缓存。
- 二级缓存 – 默认没有开启,需要手动配置才可以使用的.二级缓存可以在多个 session 中共享数据,二级缓存称为是 sessionFactory 级别的缓存。
Session 对象的缓存概述
- Session 接口中,有一系列的 java 的集合,这些 java 集合构成了 Session 级别的缓存( 一级缓存). 将对象存入到一级缓存中,session 没有结束生命周期,那么对象在session 中存放着。
- 内存中包含 Session 实例 –> Session 的缓存(一些集合) –> 集合中包含的是缓存对象。
证明一级缓存的存在,编写查询的代码即可证明。
在同一个 Session 对象中两次查询,可以证明使用了缓存。Hibernate 框架是如何做到数据发生变化时进行同步操作的呢?
- 使用 get 方法查询 User 对象。
- 然后设置 User 对象的一个属性,注意:没有做 update 操作。发现,数据库中的记录也改变了。
- 利用快照机制来完成的(SnapShot)。
2. 证明一级缓存的存在性
通过多次查询同一个对象数据,得到同一个对象,且第二次不再从数据库查询,证明一级缓存存在。
一级缓存的存在性实例1
1、新建 TestUser 类
/Hibernate5_d02_c03/src/hibernate/test/TestUser.java
程序代码如下:
package hibernate.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import hibernate.domain.User;
import hibernate.util.HibernateUtils;
public class TestUser {
//查看一级缓存是否存在
@Test
public void getUser1(){
//获取 session
Session session = HibernateUtils.openSession();
Transaction tr = session.beginTransaction();
//第一次查询,从数据库中取数据,必然发出 sql 语句
User user = session.get(User.class, 2);
System.out.println(user + "||" + user.getName());
//第二次查询,从缓存中取数据,不发sql,证明hibernate的一级缓存存在
User user2 = session.get(User.class, 2);
System.out.println(user2 + "||" + user2.getName());
tr.commit();
session.close();
}
}
2、测试观察结果只发出一条 sql 语句,说明一级缓存存在。
![运行效果](https://i-blog.csdnimg.cn/blog_migrate/babf5fb70193ea21e58201c403c4ced9.jpeg)
一级缓存的存在性实例2
1、修改TestUser 类
/Hibernate5_d02_c03/src/hibernate/test/TestUser.java
程序代码如下:
package hibernate.test;
import java.io.Serializable;
...
public class TestUser {
...
@Test
public void getUser2(){
//1.获取 session
Session session = HibernateUtils.openSession();
Transaction tr = session.beginTransaction();
//2.新建一个 user 对象
User user = new User();
user.setName("小六");
user.setAge(18);
//3.保存对象,发送 sql 语句,返回保存的 OID,并且把对象保存在一级缓存中
Serializable oid = session.save(user);
tr.commit();
//4.不要关闭session,通过返回 id 直接从一级缓存中获取数据,不会发送 sql 语句
//用同一个session去缓存中取数据
User user2 = session.get(User.class, oid);
//两个对象是同一个
System.out.println(user + "||" + user.getName());
System.out.println(user2 + "||" + user2.getName());
session.close();
}
}
2、查看结果,只发送一条 sql 语句,说明一级缓存存在。
![运行结果](https://i-blog.csdnimg.cn/blog_migrate/63c262297ea08a91c0bea47a499310c4.jpeg)
3. 一级缓存中的快照机制
1、修改TestUser 类
/Hibernate5_d02_c03/src/hibernate/test/TestUser.java
程序代码如下:
...
public class TestUser {
...
@Test
public void testUpdate(){
//获取 session
Session session = HibernateUtils.openSession();
Transaction tr = session.beginTransaction();
User user = session.get(User.class, 1);
user.setName("小明");
//持久化对象有自动更新数据库的能力,所以不用写update语句也可以更新
//session.update(user);
tr.commit();
session.close();
}
}
2、运行结果
![运行结果](https://i-blog.csdnimg.cn/blog_migrate/4a581a358123e974a758f38010a5f189.jpeg)
3、分析
![图解分析](https://i-blog.csdnimg.cn/blog_migrate/a19489ada304513248e4abcc69df80df.jpeg)