Hibernate缓存的evict、clear和flush方法
2016-03-27 19:24
429 查看
evict()、clear()和flush()方法是Hibernate缓存的3种基本操作方法,本文主要介绍这3种方法的使用方式和具体区别。
Company表:
Company实体类:
evict()和clear()方法都是从session中清除缓存,evict()是清除单个对象的缓存,而clear()是清除所有缓存。测试方法如下:
B:此处打印出:KONAMI。
C:此处取缓存,不会发SQL。
D:此处打印出:KONAMI。
下面我们在第二次get之前先清除缓存:
2. flush()方法
flush()方法会根据缓存中对象的操作生成相应的SQL语句去操作数据库。没有调用flush()的测试方法如下:
B:此处会发出insert语句去更新数据库,但数据是未提交的状态,如果数据库的隔离级别是Read Committed的话就可以看到。
下面我们自己来调用flush()方法:
B:此处会发出insert语句去更新数据库。数据是未提交的状态。
注意:Hibernate使用的主键生成策略为uuid时情况会有所不同,我们把Company实体类的companyId属性的类型改为String,再把Company hbm配置修改为<generator class="uuid">。下面还是使用上面的测试方法:
C:这个地方很关键,我们先看看Hibernate生成的SQL语句:
本文出自 “銅鑼衛門” 博客,请务必保留此出处http://jaeger.blog.51cto.com/11064196/1757270
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()); //DA:此处发出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); //A Company newCompany = new Company(); newCompany.setCompanyName("UBISOFT"); session.save(newCompany); //B transaction.commit(); //C session.close();A:此处不会发出SQL去更新数据库。
B:此处会发出insert语句去更新数据库,但数据是未提交的状态,如果数据库的隔离级别是Read Committed的话就可以看到。
insert into company (company_name) values (?)C:此处会发出update语句去更新company信息。
update company set company_name=? where company_id=?这里之所以会发出SQL语句,因为transaction.commit()会调用flush()方法。
下面我们自己来调用flush()方法:
Company company = (Company)session.get(Company.class, 1); company.setCompanyName("Santa Monica"); session.update(company); session.flush(); //A Company 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); //A Company 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从上面可以看出:Hibernate在用缓存中的对象去操作数据库时,并不是按照我们程序的顺序去执行,而是先执行insert,然后才执行update和delete。这就有可能让执行结果跟我们所期待的不一样。这个时候就应该使用flush()方法手动的让Hibernate及时去发送SQL语句。上面的例子中,我们如果在A步骤后面加入session.flush()方法,则update就会比insert先执行。
into
company
(company_name, company_id)
values
(?, ?)
update company set company_name=? where company_id=?
本文出自 “銅鑼衛門” 博客,请务必保留此出处http://jaeger.blog.51cto.com/11064196/1757270
相关文章推荐
- 一百个灯泡排成一排,第一轮将所有灯泡打开;
- Swift中创建一个UIBarButtonItem的分类
- iOS中 动态热修补技术JSPatch 韩俊强的博客
- iOS中 动态热修补技术JSPatch 韩俊强的博客
- hdu5653 Bomber Man wants to bomb an Array.
- myBatis的工作流程
- 学习使用LATEX排版
- 华为2016校招上机笔试题第一题
- TCP/IP四层模型 简单介绍一下TCP/IP模型
- js 匿名函数和闭包函数(js练习)
- 敏捷开发方法综述
- Android 第七天重置版_样式主题国际化动画对话框
- Option '--debug-info' used, but is disabled/mysqlslap --debuginfo被禁止
- 局部变量和全局变量
- lintcdoe:Merge k Sorted Lists
- 深入浅出nodejs学习笔记——nodejs简介
- C++<Algorithm>学习
- PAT1054. The Dominant Color (20)
- PyQt4简单的窗口程序
- 友盟第三方分享