缓存概述
什么是Hibernate缓存:
- 并不是指内存或者cpu的一二级缓存。
- 缓存是指为了降低应用程序对物理数据资源访问的频次,从而提高应用程序运行性能的一种策略。(简单地说就是为了在ORM框架中更快速地检索数据库,拿到我们想要的数据)
为什么使用缓存:
- ORM框架访问数据库的效率直接影响应用程序的运行速度,提升和优化ORM框架的执行效率至关重要。
- Hibernate的缓存是提升和优化Hibernate执行效率的重要手段,所以学会Hibernate缓存的使用和配置是优化的关键。
缓存的工作原理:
- 将物理数据源(数据库)中的数据复制到缓存中,缓存又是存放在应用程序的内存中,在获取数据时可以直接从应用程序的内存中取,而不需要再去访问数据库获取数据。
缓存工作的流程:
缓存命中:
- 什么是缓存命中和未命中:缓存中如果存在要被访问的数据时就叫做命中,如果没有的话需要回原服务器取,就是没有命中。
- 缓存命中率越高,数据库查询的次数就越少。
缓存的简单测试
1、执行testQueryStudent()对数据库中的学生字段进行查询:
public class StudentTest {
private SessionFactory sessionFactory;
private Session session;
private Transaction transaction;
@Before
public void init() {
// 创建配置对象
Configuration config = new Configuration().configure();
// 创建服务注册对象
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(config.getProperties()).buildServiceRegistry();
// 创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistry);
// 打开会话
session = sessionFactory.openSession();
// 开启事务
transaction = session.beginTransaction();
}
@Test
public void testAddStudent() {
// 添加学生对象
Student student = new Student(1, "小明", "男", new Date(), "中国");
session.save(student);
}
@Test
public void testQueryStudent() {
Student student = (Student)session.get(Student.class, 1);
System.out.println(student);
}
@After
public void destroy() {
// 提交事务
transaction.commit();
// 关闭会话
session.close();
// 关闭会话工厂
sessionFactory.close();
}
}
执行结果如图所示:
2、我们再将testQueryStudent()稍作修改:
@Test
public void testQueryStudent() {
Student student = (Student)session.get(Student.class, 1);
System.out.println(student.getSname());
student = (Student)session.get(Student.class, 1);
System.out.println(student.getSname());
}
执行结果如图所示:
从上述操作中看出第二次查询同一个对象时,没有再次执行数据库查询操作。因为在第二次查询同一个对象时,程序先去缓存中进行查找,发现缓存命中,所以直接从缓存中取出对象,因此也没有去访问数据库。
3、我们继续修改testQueryStudent()方法,让方法从不同的session中获取相同的对象并进行观察:
@Test
public void testQueryStudent() {
Student student = (Student)session.get(Student.class, 1);
System.out.println(student.getSname());
// 从不同session种查询同一个对象
Session session1 = sessionFactory.openSession();
student = (Student) session1.get(Student.class, 1);
System.out.println(student.getSname());
}
执行结果如图所示:
从执行结果看出查询操作执行了两次,第二次查询不能够获取到缓存,因此我们使用不同session进行同一对象查询,会进行多次数据库的访问。