文章目录

  • 一、对象状态
    • 1.1 临时/瞬时状态
    • 1.2 持久化状态
    • 1.3 游离状态
  • 二、一级缓存
    • 2.1 含义
    • 2.2 缓存相关的方法
      • 2.2.1 clear
      • 2.2.2 flush
      • 2.2.3 方法适用场景
    • 2.3 Iterator与list
    • 2.4 懒加载
      • 2.4.1 修改懒加载
      • 2.4.2 懒加载异常
  • 三、二级缓存
    • 3.1 含义
    • 3.2 配置二级缓存
      • 3.2.1 开启二级缓存
      • 3.2.2 指定缓存框架
      • 3.2.3 指定哪些类加入二级缓存
      • 3.2.4 测试
    • 3.3 二级缓存策略
    • 3.4 集合缓存
      • 3.4.1 集合配置二级缓存
      • 3.4.2 测试
    • 3.5 查询缓存

一、对象状态

参考:https://mp.weixin.qq.com/s/VFnny3ou48w9bIgTT0xVow

1.1 临时/瞬时状态

含义:直接new出来的对象就是临时/瞬时状态的。
特点:
——该对象还没有被持久化【没有保存在数据库中】
——不受Session的管理

User user = new User();
IdCard idCard = new IdCard();
// 这样,对象处于临时/瞬时状态了

1.2 持久化状态

含义:当保存在数据库中的对象就是持久化状态。
当调用session的save/saveOrUpdate/get/load/list等方法时,对象就是持久化状态
特点:
——在数据库有对应的数据
——受Session的管理
——当对对象属性进行更改的时候,会反映到数据库中!

session.save(idCard);
transaction.commit();
// 这样,对象处于持久化状态了。

1.3 游离状态

含义:当Session关闭了以后,持久化的对象就变成了游离状态了。
特点:
——在数据库有对应的数据
——不处于session的管理

session.save(idCard);
transaction.commit();
session.close();
// 这样,对象处于游离状态了。

二、一级缓存

2.1 含义

项目 含义
Hibenate中一级缓存 也叫做session的缓存。
目的 在session范围内,减少对数据库的访问次数!从而提升hibernate的执行效率!
有效范围 session。 Session关闭,一级缓存失效!

注意
1、持久化状态的对象,都受Session管理,都会在Session缓存中!
2、Session的缓存由hibernate维护,用户不能操作缓存内容。
3、 若想操作缓存内容,必须通过hibernate提供的evit/clear方法操作。

示例说明:
1、更新数据库
已知:user表中(id = 1,username=“张珊”)。
目的:把id=1的username改为“张珊”。

// 获取id=1的对象信息。
User user = (User)session.get(User.class,1);
// 修改username为“张珊”。
user.setUsername("张珊");
// 提交事务。
transaction.commit();
// 关闭session。
session.close();

结果:只有一条查询SQL,并没有更新SQL。
原因:查询的结果被缓存了。修改后的数据与缓存的数据一样,所以没有执行更新操作。
2、获取数据
已知:user表中(id = 1,username=“张珊”)。
目的:二次获取该信息。

User user = null;
user = (User)session.get(User.class,1); // 一次获取
user = (User)session.get(User.class,1);// 二次获取
// 提交事务。
transaction.commit();
// 关闭session。
session.close();

结果:只有一条查询SQL。
原因:一次查询的结果被缓存了。 二次获取直接从缓存中获取。

2.2 缓存相关的方法

常用的方法 作用
session.flush(); 让一级缓存与数据库同步
session.evict(arg0); 清空一级缓存中指定的对象
session.clear(); 清空一级缓存中缓存的所有对象

2.2.1 clear

 User user = null;
user = (User) session.get(User.class, 1);
//清除缓存,那么下面获取的时候,就不能从缓存里面拿了
session.clear();
user = (User) session.get(User.class, 1);
// 结果:执行两次查询语句。

2.2.2 flush

在有缓存的情况下,修改同一条记录的数据,以最后的为准…因此只有一条update

User user = null;
user = (User) session.get(User.class, 1);
user.setUsername("李四");
user = (User) session.get(User.class, 1);
user.setUsername("王五");
// 结果:执行一次更新SQL语句。

强制让它和数据库同步的话,就有两条update了

User user = null;
user = (User) session.get(User.class, 1);
user.setUsername("李四");
session.flush();
user = (User) session.get(User.class, 1);
user.setUsername("王五");
// 结果:执行两次更新SQL语句。

2.2.3 方法适用场景

一般地,我们在批处理的时候会用,因为缓存也是有大小的。
思路:
——每隔一定记录数,先与数据库同步 flush()
——再清空缓存 clear()
注意:不同的Session是不会共享缓存的!

2.3 Iterator与list

使用HQL查询全部数据的时候,可以使用list()得到所有的数据,也可以使用iterator()得到一个迭代器,再遍历迭代器。
二者都可以获取缓存的数据。

2.4 懒加载

含义:当使用数据的时候才去获取数据、执行对应的SQL语句…当还没用到数据的时候,就不加载对应的数据!
作用:提高Hibernate的性能,提高执行效率!
——get: 及时加载,只要调用get方法立刻向数据库查询
——load:默认使用懒加载,当用到数据的时候才向数据库查询。

user = (User) session.get(User.class, 1);
user = (User) session.load(User.class, 1);

2.4.1 修改懒加载

<class name="IdCard" table="IdCard" lazy="false">

属性值:
true 使用懒加载
false 关闭懒加载
extra (在集合数据懒加载时候提升效率)【只有在set、list等集合标签中使用】
——在真正使用数据的时候才向数据库发送查询的sql;
——如果调用集合的size()/isEmpty()方法,只是统计,不真正查询数据!

2.4.2 懒加载异常

当Session关闭后,就不能使用懒加载了,否则会报出异常。

session.close();
System.out.println(user);
// 结果:报出异常。
异常解决方法 含义 示例
方式1 先使用一下数据 dept.getDeptName();
方式2 强迫代理对象初始化 Hibernate.initialize(dept);
方式3 关闭懒加载 设置lazy=false;
方式4 在使用数据之后,再关闭session!

三、二级缓存

3.1 含义

项目 含义
来源 Hibernate自带
含义 基于应用程序的缓存
范围 所有的Session都可以使用
存储内容 存储的是常用的类

注意:Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!
——若想用二级缓存,只需在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。
——若觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。

3.2 配置二级缓存

二级缓存是Hibernate自带的,可以在hibernate.properties文件中找到对应的信息。
hibernate.properties:

#hibernate.cache.use_second_level_cache false【二级缓存默认不开启,需要手动开启】
#hibernate.cache.use_query_cache true      【开启查询缓存】
## choose a cache implementation        【二级缓存框架的实现】
#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_class org.hibernate.cache.HashtableCacheProvider 默认实现
#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider

配置步骤:
1)开启二级缓存
2)指定缓存框架
3)指定哪些类加入二级缓存

3.2.1 开启二级缓存

在hibernate.cfg.xml文件中开启二级缓存

<!-- a.  开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>

3.2.2 指定缓存框架

指定Hibernate自带的二级缓存框架就好了

  <!-- b. 指定使用哪一个缓存框架(默认提供的) -->
<property name="hibernate.cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>

3.2.3 指定哪些类加入二级缓存

<!-- c. 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="com.my.entity.Monkey"/>
<class-cache usage="read-only" class="com.my.entity.Cat"/>

3.2.4 测试

一级缓存是Session的缓存,那么我们在测试二级缓存的时候使用两个Session来测试就好了。如果第二个Session拿到的是缓存数据,那么就证明二级缓存是有用的。

public static void testCache2() {Session session1 = getSession();Transaction transaction = session1.getTransaction();transaction.begin();Monkey monkey = (Monkey) session1.get(Monkey.class,"40283f815be67f42015be67f43240001" );System.out.println(monkey.getName());Session session2 = factory.openSession();Transaction transaction2 = session2.getTransaction();transaction2.begin();Monkey monkey2 = (Monkey) session1.get(Monkey.class, "40283f815be67f42015be67f43240001");System.out.println(monkey2.getName());//提交事务transaction.commit();transaction2.commit();//关闭Sessionsession1.close();session2.close();
}

结果:只有一个查询语句。输出正确结果。说明二级缓存生效。

3.3 二级缓存策略

<!-- c. 指定哪一些类,需要加入二级缓存 -->
<class-cache usage="read-write" class="com.my.entity.Monkey"/>
<class-cache usage="read-only" class="com.my.entity.Cat"/>
属性值 含义
read-only 放入二级缓存的对象,只读;
read-write 放入二级缓存的对象,可以读、写;

非严格的读写
(基于事务的策略)

3.4 集合缓存

问题:在数据库查询的数据是集合时,Hibernate默认是没有为集合数据设置二级缓存的。因此,还需要去读写数据库的信息。

3.4.1 集合配置二级缓存

在hibernate.cgf.xml中配置对象中的集合为二级缓存。

<!-- 集合缓存[集合缓存的元素对象,也加加入二级缓存] -->
<collection-cache usage="read-write" collection="cn.itcast.b_second_cache.Dept.emps"/>

3.4.2 测试

public static void testCache() {Session session1 = sf.openSession();session1.beginTransaction();// a. 查询一次Dept dept = (Dept) session1.get(Dept.class, 10);dept.getEmps().size();// 集合session1.getTransaction().commit();session1.close();System.out.println("------");// 第二个sessionSession session2 = sf.openSession();session2.beginTransaction();// a. 查询一次dept = (Dept) session2.get(Dept.class, 10);  // 二级缓存配置好; 这里不查询数据库  dept.getEmps().size();session2.getTransaction().commit();session2.close();
}

3.5 查询缓存

问题:list()和iterator()会把数据放在一级缓存,但一级缓存只在Session的作用域中有效。如果想要跨Session来使用,就要设置查询缓存

1、默认的查询数据是不放在二级缓存中的。
2、若想把查询数据放到二级缓存,就需要在配置文件中开启。

 <!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>

在使用程序查询的时候,也要调用setCacheable()方法,设置为查询缓存。

public static void listCache() {Session session1 = sf.openSession();session1.beginTransaction();// HQL查询  【setCacheable  指定从二级缓存找,或者是放入二级缓存】Query q = session1.createQuery("from Dept").setCacheable(true);System.out.println(q.list());session1.getTransaction().commit();session1.close();Session session2 = sf.openSession();session2.beginTransaction();q = session2.createQuery("from Dept").setCacheable(true);System.out.println(q.list());  // 不查询数据库: 需要开启查询缓存session2.getTransaction().commit();session2.close();}

Hibernate——缓存相关推荐

  1. Hibernate缓存原理与策略 Hibernate缓存原理:

    Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...

  2. Hibernate 缓存机制

    转载:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...

  3. Hibernate 缓存

    我这里使用的是Hibernate5.2.0版本 Hibernate缓存分为一级缓存(有的也叫Session缓存)和二级缓存. 一级缓存(Session) 一级缓存的生命周期和session的生命周期一 ...

  4. 【大话Hibernate】hibernate缓存详解

    为什么要用hibernate缓存? hibernate是一个持久层框架,经常访问物理数据库.为了降低应用程序对物理数据源访问的次数,从而提高应用程序的运行性能,我们想到使用hibernate缓存机制. ...

  5. (11) Hibernate 缓存机制

    一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...

  6. 初识Hibernate 缓存

    生活就像一杯咖啡,让你我慢慢的品尝,品尝它的苦涩和甘甜...... 一.什么是Hibernate缓存. 解析:白话来说就是缓存数据的容器 官方标准点缓存:是计算机领域的概念,它介于应用程序和永久性数据 ...

  7. hazelcast 使用_使用HazelCast进行Hibernate缓存:JPA缓存基础知识

    hazelcast 使用 HazelCast的最大功能之一就是对Hibernate第二级缓存的支持 . JPA具有两个级别的缓存. 一级缓存在事务期间缓存对象的状态. 通过两次查询相同的对象,您必须获 ...

  8. Hibernate缓存级别教程

    开始使用Hibernate的人们常见的问题之一就是性能,如果您没有太多的Hibernate经验,您会发现应用程序变慢的速度. 如果启用sql跟踪,您将看到有多少查询被发送到数据库,而这些查询几乎不需要 ...

  9. hibernate缓存机制与N+1问题

    在项目中遇到的趣事 本文基于hibernate缓存机制与N+1问题展开思考, 先介绍何为N+1问题 再hibernate中用list()获得对象: 1 /** 2 * 此时会发出一条sql,将30个学 ...

  10. Hibernate缓存 - 第一级缓存

    Hibernate缓存 - 第一级缓存 欢迎使用Hibernate缓存 - 一级缓存示例教程.最近我们研究了Hibernate架构,hibernate映射以及如何使用HQL以面向对象的方式触发SQL查 ...

最新文章

  1. ASP.NET Core 源码学习之 Options[4]:IOptionsMonitor
  2. python语言中包含的标准数据类型_python标准数据类型(笔记一)
  3. 解决 An invalid domain was specified for this cookie
  4. Linux API函数总结
  5. python seo百度_Python与seo,百度关键词相关搜索关键词采集源码
  6. Isolate -- Be Forget Feature Of The Object-Orient Programming
  7. 数字图像处理-空间域图像增强
  8. 镜头相关的基本参数总结
  9. 安装好office套件以后,右键新建中没有Word、Excel、PPT等怎么办
  10. 给陈景润之子陈由伟的一封公开信
  11. 用计算机画画教学设计,电脑版你画画教学设计
  12. Unable to start service Intent U=0: not found
  13. I. chino with mates
  14. Python扩展包:Unofficial Windows Binaries for Python Extension Packages
  15. Location iOS12.3驱动分享
  16. 中班音乐会跳舞的机器人_中班音乐《会跳舞的身体》
  17. 被人打了要不要还手呢?
  18. MediaPlayer,切歌进入setOnCompletionListener的问题
  19. 基于51单片机NRF24L01的远程水压监控及控制proteus仿真原理图PCB
  20. Java实验报告一(完全数、一年四季、杨辉三角、path和classpath区别、next()和nextLine()区别)

热门文章

  1. TBtools:基因家族分析简单流程
  2. 计算机显示屏显示超出屏幕大小,电脑连接的显示器出错显示超出工作频率范围怎么恢复...
  3. vue网页调用高德获取经纬度
  4. centos:清理磁盘空间
  5. 图像相似度的评价指标 : FID(Fréchet Inception Distance)
  6. CC2430 定时器溢出中断 详解
  7. ant-desigh+prolayout布局,修改面包屑的分隔符号,百度搜遍了都找不到办法,csdn解决了
  8. 企业财务报表分析【1】
  9. win10计算机域填写,win10系统如何加入域 win10系统加入域的方法
  10. 设计模式(三) 抽象工厂模式