evict()、clear()和flush()方法是Hibernate缓存的3种基本操作方法,本文主要介绍这3种方法的使用方式和具体区别。

Company表:

Company实体类:

import java.util.Set;public class Company {private int companyId;private String companyName;private Set<Employee> companyEmployees;public int getCompanyId() {return companyId;}public void setCompanyId(int companyId) {this.companyId = companyId;}public String getCompanyName() {return companyName;}public void setCompanyName(String companyName) {this.companyName = companyName;}public Set<Employee> getCompanyEmployees() {return companyEmployees;}public void setCompanyEmployees(Set<Employee> companyEmployees) {this.companyEmployees = companyEmployees;}
}

Company hbm配置:

<hibernate-mapping><class name="com.jaeger.hibernatetest.day7.lazy.Company" table="company"><id name="companyId" column="company_id"><generator class="native"></generator></id><property name="companyName" column="company_name"/><set name="companyEmployees"><key column="employee_company_id"></key><one-to-many class="com.jaeger.hibernatetest.day7.lazy.Employee"/></set></class>
</hibernate-mapping>

1. evict()和clear()方法
evict()和clear()方法都是从session中清除缓存,evict()是清除单个对象的缓存,而clear()是清除所有缓存。测试方法如下:

Company company = (Company)session.get(Company.class, 1); //A
System.out.println(company.getCompanyName()); //B
company = (Company)session.get(Company.class, 1);  //C
System.out.println(company.getCompanyName()); //D

A:此处发出SQL去数据库查询。
B:此处打印出:KONAMI。
C:此处取缓存,不会发SQL。
D:此处打印出:KONAMI。
下面我们在第二次get之前先清除缓存:

Company company = (Company)session.get(Company.class, 1); //A
System.out.println(company.getCompanyName());
session.evict(company); //B
company = (Company)session.get(Company.class, 1);  //C
System.out.println(company.getCompanyName());

A、C:这两处都会发相同的SQL去数据库查询。因为B处清除了缓存,调用clear()方法效果也是一样。


2. flush()方法

flush()方法会根据缓存中对象的操作生成相应的SQL语句去操作数据库。没有调用flush()的测试方法如下:

Company company = (Company)session.get(Company.class, 1);
company.setCompanyName("Santa Monica");
session.update(company); //ACompany newCompany = new Company();
newCompany.setCompanyName("UBISOFT");
session.save(newCompany); //B
transaction.commit(); //C
session.close();

A:此处不会发出SQL去更新数据库。

B:此处会发出insert语句去更新数据库,但数据是未提交的状态,如果数据库的隔离级别是Read Committed的话就可以看到。

insert  intocompany(company_name)
values(?)

C:此处会发出update语句去更新company信息。

updatecompany setcompany_name=? wherecompany_id=?

这里之所以会发出SQL语句,因为transaction.commit()会调用flush()方法。

下面我们自己来调用flush()方法:

Company company = (Company)session.get(Company.class, 1);
company.setCompanyName("Santa Monica");
session.update(company);
session.flush(); //ACompany newCompany = new Company();
newCompany.setCompanyName("UBISOFT");
session.save(newCompany);
transaction.commit(); //B
session.close();

A:此处立刻会发出update语句去更新company信息。数据是未提交的状态。

B:此处会发出insert语句去更新数据库。数据是未提交的状态。

注意:Hibernate使用的主键生成策略为uuid时情况会有所不同,我们把Company实体类的companyId属性的类型改为String,再把Company hbm配置修改为<generator class="uuid">。下面还是使用上面的测试方法:

Company company = (Company)session.get(Company.class, 1);
company.setCompanyName("Santa Monica");
session.update(company); //ACompany newCompany = new Company();
newCompany.setCompanyName("UBISOFT");
session.save(newCompany); //B
transaction.commit(); //C
session.close();

A、B:这时update()和save()都不会向数据库发SQL语句,第一次测试中save()方法会发SQL语句是因为我们使用的是native主键生成策略,要拿到主键就必须先向数据库插入数据。而uuid是Hibernate自己生成的,所以只会加入缓存,而不会发出SQL语句。

C:这个地方很关键,我们先看看Hibernate生成的SQL语句:

insert intocompany(company_name, company_id)
values(?, ?)updatecompany setcompany_name=? wherecompany_id=?

从上面可以看出:Hibernate在用缓存中的对象去操作数据库时,并不是按照我们程序的顺序去执行,而是先执行insert,然后才执行update和delete。这就有可能让执行结果跟我们所期待的不一样。这个时候就应该使用flush()方法手动的让Hibernate及时去发送SQL语句。上面的例子中,我们如果在A步骤后面加入session.flush()方法,则update就会比insert先执行。

转载于:https://blog.51cto.com/jaeger/1757270

Hibernate缓存的evict、clear和flush方法相关推荐

  1. Hibernate 缓存的使用

    hibernate cache 缓存 1. 关于hibernate缓存的问题: 1.1.1. 基本的缓存原理 Hibernate缓存分为二级,第一级存放于session中称为一级缓存,默认带有且不能卸 ...

  2. 【转】Hibernate中session的clear(),flush(),evict()方法详解

    1.Clear 方法 无论是Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强制清除Session缓存. 例: [java] view ...

  3. Hibernate中session的clear(),flush(),evict()方法详解

    一.Clear 方法 无论是Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强制清除Session缓存.例: public void t ...

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

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

  5. Hibernate 缓存机制

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

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

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

  7. (11) Hibernate 缓存机制

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

  8. hibernate缓存理解

    为什么80%的码农都做不了架构师?>>> 1)Hibenate中一级缓存,也叫做session的缓存,它可以在session范围内减少数据库的访问次数!  只在session范围有效 ...

  9. Hibernate学习——(十二)Hibernate缓存机制(一级、二级、查询)

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

  10. Hibernate缓存 - 第一级缓存

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

最新文章

  1. 企业网站做SEO优化必走的三条路线,希望新人前方不要右转
  2. 零基础学python看什么书-零基础学python推荐几本python学习的书籍
  3. MoCoV3:何恺明团队新作!解决Transformer自监督训练不稳定问题!
  4. mysql2005卸载步骤,二次安装mysql步骤
  5. ldap和kerberos整合大数据账号
  6. iframe-父子-兄弟页面相互传值(jq和js两种方法)
  7. thymeleaf比较符号问题
  8. Docker学习总结(24)——在Docker中监视Java应用程序的5种方法
  9. C语言库函数学习知识
  10. 全国高校名单及地理位置经纬度信息(含分校区)
  11. 激光雷达简介及物体检测(一)
  12. C报错ld returned 1 exit status可能的原因
  13. vbscript错误代码及对应解释大全
  14. 使用手机+ardinuo+esp01做的网络时钟
  15. 4.2-知识图谱在电商领域中的应用实践
  16. vue2/vue3详细知识点
  17. MacW编辑部的电脑都装了哪些苹果应用?
  18. 程序员常用英语词汇(018)
  19. python拆分字符串生成列表_关于python:如何将字符串拆分为列表?
  20. 基于达尔文进化论的遗传算法,还能帮你破解同事的密码?| 附代码

热门文章

  1. 重置SQLSERVER表的自增列,让自增列重新计数【转】
  2. 从44.556677想到的
  3. Redis环境配置和命令语句
  4. 【MySQL学习笔记】MySQL库与表
  5. 学习Cocos2d的博客 --推荐
  6. 整数输入问题一百二十九:阿基米德特性
  7. 如何将SL的image保存到SL的独立存储文件系统
  8. 从0开始运行flutter helloworld笔记
  9. docker搭建sonarqube做代码审计
  10. git常用命令及手动关联git本地和远端仓库