Hibernate缓存的evict、clear和flush方法
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方法相关推荐
- Hibernate 缓存的使用
hibernate cache 缓存 1. 关于hibernate缓存的问题: 1.1.1. 基本的缓存原理 Hibernate缓存分为二级,第一级存放于session中称为一级缓存,默认带有且不能卸 ...
- 【转】Hibernate中session的clear(),flush(),evict()方法详解
1.Clear 方法 无论是Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强制清除Session缓存. 例: [java] view ...
- Hibernate中session的clear(),flush(),evict()方法详解
一.Clear 方法 无论是Load 还是 Get 都会首先查找缓存(一级缓存) 如果没有,才会去数据库查找,调用Clear() 方法,可以强制清除Session缓存.例: public void t ...
- Hibernate缓存原理与策略 Hibernate缓存原理:
Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...
- Hibernate 缓存机制
转载:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html 一.why(为什么要用Hibernate缓存?) Hibernate是一个 ...
- 【大话Hibernate】hibernate缓存详解
为什么要用hibernate缓存? hibernate是一个持久层框架,经常访问物理数据库.为了降低应用程序对物理数据源访问的次数,从而提高应用程序的运行性能,我们想到使用hibernate缓存机制. ...
- (11) Hibernate 缓存机制
一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...
- hibernate缓存理解
为什么80%的码农都做不了架构师?>>> 1)Hibenate中一级缓存,也叫做session的缓存,它可以在session范围内减少数据库的访问次数! 只在session范围有效 ...
- Hibernate学习——(十二)Hibernate缓存机制(一级、二级、查询)
一.why(为什么要用Hibernate缓存?) Hibernate是一个持久层框架,经常访问物理数据库. 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能. 缓存内的数据是对物理数 ...
- Hibernate缓存 - 第一级缓存
Hibernate缓存 - 第一级缓存 欢迎使用Hibernate缓存 - 一级缓存示例教程.最近我们研究了Hibernate架构,hibernate映射以及如何使用HQL以面向对象的方式触发SQL查 ...
最新文章
- 企业网站做SEO优化必走的三条路线,希望新人前方不要右转
- 零基础学python看什么书-零基础学python推荐几本python学习的书籍
- MoCoV3:何恺明团队新作!解决Transformer自监督训练不稳定问题!
- mysql2005卸载步骤,二次安装mysql步骤
- ldap和kerberos整合大数据账号
- iframe-父子-兄弟页面相互传值(jq和js两种方法)
- thymeleaf比较符号问题
- Docker学习总结(24)——在Docker中监视Java应用程序的5种方法
- C语言库函数学习知识
- 全国高校名单及地理位置经纬度信息(含分校区)
- 激光雷达简介及物体检测(一)
- C报错ld returned 1 exit status可能的原因
- vbscript错误代码及对应解释大全
- 使用手机+ardinuo+esp01做的网络时钟
- 4.2-知识图谱在电商领域中的应用实践
- vue2/vue3详细知识点
- MacW编辑部的电脑都装了哪些苹果应用?
- 程序员常用英语词汇(018)
- python拆分字符串生成列表_关于python:如何将字符串拆分为列表?
- 基于达尔文进化论的遗传算法,还能帮你破解同事的密码?| 附代码