Hibernate缓存浅析

Hibernate缓存浅析

第一次用markdown写博客,小激动!!!

  • 一级缓存
  • 二级缓存
  • 会话(session)级缓存
  • 全局缓存

hibernate缓存的作用

-并不是指计算机或者内存的一二级缓存
-缓存的目的是为了降低应用程序对物理数据源访问的次数从而提高应用程序运行性能的一种策略
-使用缓存的目的是为了提升和优化hibernate的执行效率

hibernate缓存的一般工作原理

Created with Raphaël 2.1.0 应用程序 操作 缓存命中? 数据库 yes no

-在hibernate中查询数据时,会先检查缓存中是否存在,若存在则直接读取(称之为缓存命中)
-若不存在则直接再去数据库中读取并返回数据

一级缓存

一级缓存的特点

-用户不可关闭
-缓存生命周期与其对应的session相同
-再同一个session中对同一个对象多次查询仅会发出一次sql语句
-在不同的session进行查询会发出多次sql语句即不同的session对应不同的一级缓存

在同一session种执行两次查询

        // 创建 hibernate 配置对象
        Configuration configuration = new Configuration().configure();
        // 创建服务注册对象
        org.hibernate.service.ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        // 生成SessionFactory
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry);
        // 创建session
        Session session = sessionFactory.getCurrentSession();
        // 创建事务
        Transaction transaction = session.beginTransaction();

         StudentsPK pk = new StudentsPK();
         pk.setId(789);
         pk.setSid(456);
         Students students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());

控制台输出结果
我们可以看到hibernate框架只发出了一次sql语句
而打印了两次结果

在不同session中执行查询

        // 创建 hibernate 配置对象
        Configuration configuration = new Configuration().configure();
        // 创建服务注册对象
        org.hibernate.service.ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        // 生成SessionFactory
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry);
        // 创建session
        Session session = sessionFactory.getCurrentSession();
        // 创建事务
        Transaction transaction = session.beginTransaction();

         StudentsPK pk = new StudentsPK();
         pk.setId(789);
         pk.setSid(456);
         Students students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         Session session2 = sessionFactory.openSession();
         students = (Students) session2.get(Students.class, pk);
         System.out.println(students.getSname());

控制台输出结果
在不同的session中我们进行查询可以看到输出了两次sql语句
证明不同的session用的不是同一个一级缓存

一级缓存的两个常用方法

-一级缓存无法取消,采用两个方法进行管理
-evict():用于将某个对象从一级缓存中删除
-clear():用于将一级缓存中所有对象清除

evict()的使用

        // 创建 hibernate 配置对象
        Configuration configuration = new Configuration().configure();
        // 创建服务注册对象
        org.hibernate.service.ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        // 生成SessionFactory
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry);
        // 创建session
        Session session = sessionFactory.getCurrentSession();
        // 创建事务
        Transaction transaction = session.beginTransaction();

         StudentsPK pk = new StudentsPK();
         pk.setId(789);
         pk.setSid(456);
         Students students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         // 将对象删除
         session.evict(students);
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());

控制台输出
我们可以在同一session中进行两次查询,因为中间有删除对象的操作所以发出了两次sql语句

clear()的使用

        // 创建 hibernate 配置对象
        Configuration configuration = new Configuration().configure();
        // 创建服务注册对象
        org.hibernate.service.ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                .applySettings(configuration.getProperties()).build();
        // 生成SessionFactory
        SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(serviceRegistry);
        // 创建session
        Session session = sessionFactory.getCurrentSession();
        // 创建事务
        Transaction transaction = session.beginTransaction();

         StudentsPK pk = new StudentsPK();
         pk.setId(789);
         pk.setSid(456);
         Students students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         // 将所有对象删除
         session.clear();
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());

控制台输出
从控制台输出我们可以看到,同样执行了两次sql语句

hibernate二级缓存

-又称为“全局缓存”,“应用级缓存”
-每个session都可以访问其中的内容,即每个session都共用的缓存
-可取消、可自定义

二级缓存的配置步骤

导入相应的包
这里写图片描述
导入包的过程不赘述,在hibernate的jar里面就有,题主这里采用的是hibernate-4.3.5-final。缓存包路径为hibernate4.3.5\hibernate4.3.5\lib\optional\ehcache
在hibernate.cfg.xml配置文件中添加Provider类描述
-在配置文件中添加以下属性
这里写图片描述
-provider所在位置(已标出)
这里写图片描述

添加二级缓存的属性配置文件

-属性配置文件位置
这里写图片描述

-添加到project中
这里写图片描述

在需要被缓存的表所对应的映射文件中添加标签
这里写图片描述

代码验证二级缓存效果

-使用两个会话

         Students students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());
         session = sessionFactory.openSession();
         students = (Students) session.get(Students.class, pk);
         System.out.println(students.getSname());

-从控制台输出可以看到仅发出了一次sql语句,说明二级缓存生效
这里写图片描述

cache标签介绍

<!-- 只读事务模式,效率高 -->     
<cache usage="read-only"/>
<!-- 缓存除了PK以外其他延迟加载的属性,region="test"指定的属性是在acache.xml               配置专属缓存策略  -->
<cache usage="read-only" include="all" region="test"/>
    < cache name="test"     <!-- 标识为defaultCache表示该策略为默认策略 -->
        maxElementsInMemory="10000" <!-- 表示缓存中允许创建的最大对象数-->
        eternal="false" <!-- 表示缓存中的对象是否是永久的 -->
        timeToIdleSeconds="120" <!-- 表示缓存数据的钝化时间 -->
        timeToLiveSeconds="120" <!-- 表示缓存生存时间 -->
        overflowToDisk="true" <!-- 表示缓存溢出后是否存储在硬盘上 -->
        />

二级缓存使用情景

-很少被修改的数据
-不是很重要的数据,允许偶尔出息并发的数据
-不会被并发访问的数据
-参考数据
-策略类数据
-缓存能提高检索效率,但会占用更多的资源

总结

一二级缓存对比

-一级缓存二级缓存
缓存范围事务范围,每个事务拥有单独的一级缓存应用范围,当前应用内所有事务共享
并发访问策略无并发必须提供适当的并发访问策略
数据过期策略无数据过期策略缓存对象的最大数目、最长时间、最长空闲时间
缓存的软件实现框架内包含第三方提供,可插拔
物理介质内存内存和硬盘
启动方式默认启用,不可关闭默认不启用,选择性开启

缓存的作用
-提供检索效率但同时也会增加资源的占用和消耗

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值