hibernate学习笔记03----一级缓存
来源:互联网 发布:电脑主机 知乎 编辑:程序博客网 时间:2024/06/05 01:00
Session的一级缓存
缓存作用:
将数据缓存到内存或者硬盘上,访问这些数据,直接从内存或硬盘加载数据,无需到数据表查询.好处:快!降低数据库压力。
一级缓存的生命周期:
Session中对象集合(map),在Session创建时,对象集合(map)也就创建,缓存保存了Session对象数据,当Session销毁后,集合(map)销毁, 一级缓存释放 !
什么对象会被放入一级缓存?
只要是持久态对象,都会保存在一级缓存(与session关联的说法的本质,是将对象放入了一级缓存)
一级缓存的存在性
【示例】
通过多次查询同一个po对象数据,得到同一个对象,且第二次不再从数据库查询,证明一级缓存测存在。
//测试一级缓存的存在性@Test//测试方法:多次查询,是不是一个对象,看看有没有发出sqlpublic void testFirstCacheExist(){Session session = HibernateUtils.openSession();session.beginTransaction();//第一次查询:根据id查询//发生了:立即发出sql语句,查询数据,并将po放入一级缓存Customer customer =(Customer)session.get(Customer.class, 1);System.out.println(customer);//第二次查询//发生了:不发出sql,直接从一级缓存拿到数据(通过地址一样可以判断:是引用的同一个对象)Customer customer2 =(Customer)session.get(Customer.class, 1);System.out.println(customer2);session.getTransaction().commit();session.close();}
一级缓存的生命周期
一级缓存的生命周期就是session的生命周期,不能跨Session,可以说,一级缓存和session是共存亡的!
【示例】
使用两个不同Session来测试生命周期。(一级缓存和session共存亡)
//测试一级缓存的生命周期@Test//测试方法:关session看还能不能取到缓存的数据(看发不发sql)public void testFirstCachelifecycle(){Session session = HibernateUtils.openSession();session.beginTransaction();//从 数据库查询出数据:根据id,query对象,cretiea对象,都可以Customer customer = (Customer) session.get(Customer.class, 21);System.out.println(customer);//再次查询Customer customer2 = (Customer) session.get(Customer.class, 21);System.out.println(customer2);session.getTransaction().commit();session.close();//一级缓存随之销毁//-------------------------------------System.out.println("--------------------------------------");Session session2 = HibernateUtils.openSession();//一级缓存又重新诞生(是另外一个),但此时没数据,空的。session2.beginTransaction();//从 数据库查询出数据:根据id,query对象,cretiea对象,都可以Customer customer3 = (Customer) session2.get(Customer.class, 21);//将数据又放入一个新的一级缓存中System.out.println(customer3);//再次查询Customer customer4 = (Customer) session2.get(Customer.class, 21);//不发语句System.out.println(customer4);//地址相同session2.getTransaction().commit();session2.close();}
Session一级缓存的快照
如:
一句话:快照的作用就是用来更新数据的。
【注意】
1. 持久态对象原则:po对象尽量保持与数据库一一致。
2. 当一级缓存和快照不一致的时候,会先发出update语句,将一级缓存同步到数据库(发出update语句),然后当同步成功之后,再自动内部同步快照。保证三者的一致性。
一级缓存快照的能力
一级缓存的快照是由Hibernate来维护的,用户可以更改一级缓存(PO对象的属性值),但无法手动更改快照!
快照的主要能力(作用)是:用来更新数据!当刷出缓存的时候,如果一级缓存和快照不一致,则更新数据库数据。
【示例】
通过改变查询出来的PO的属性值,来查看一级缓存的更改;通过提交事务,来使用快照更新数据。
@Test//测试一级缓存快照的能力(更新数据)public void testSnapShot(){Session session = HibernateUtils.openSession();session.beginTransaction();//立即发出sql,并且将将数据放入一级缓存(customer是一级缓存对象的引用)和快照Customer customer =(Customer)session.get(Customer.class, 1);System.out.println(customer);//改变一级缓存的数据customer.setName("Jack1");//快照可以局部更新(不用更新所有字段)//原理:将旧的值更新上去了。//customer.setAge(88);//等待提交(会自动flush刷新缓存)//在刷新缓存的时候,会自动对比一级缓存和快照是否一致,如果不一致,则发出update语句,更新数据到数据库,,并且同步到快照//不需要手动发出update方法动作session.getTransaction().commit();session.close();}
刷出缓存的时机
什么叫刷出缓存?
Session能够在某些时间点,按照缓存中对象的变化来执行相关的SQL语句,来同步更新数据库,这一过程被成为刷出缓存(flush)。
什么情况下session会执行flush操作?
刷新缓存的三个时机:
l 事务提交commit():该方法先刷出缓存(session.flush()),然后再向数据库提交事务。
l 手动刷出flush():直接调用session.flush()。
l 查询操作:当Query查询(get、load除外,这两个会优先从一级缓存获取数据)时,如果缓存中持久化对象的属性已经发生了变化,(一级缓存和快照不一样了),则先刷出缓存,以保证查询结果能够反映出持久化对象的最新状态。
【补充理解】:
关于Hibernate如何识别是同一一个对象?(持久态)
根据OID,
问题:假如先查询出来一个对象oid是1001,数据库主键也是1001,但其他字段的属性不一样,那么,再次查询数据库的数据出来的对象,和原来的对象是否是一个对象?
答案:是!
【示例】
三种方式刷出一级缓存
@Test//刷出一级缓存的时机public void testflushcacheTime(){Session session = HibernateUtils.openSession();session.beginTransaction();//前提:先将对象放入一级缓存,--持久态对象Customer customer =(Customer)session.get(Customer.class, 1);System.out.println(customer);//改变一级缓存对象的属性值!customer.setName("Jack13");customer.setAge(88);//等待Hibernate对一级缓存进行刷新//先用get//优先走一级缓存,只会从一级缓存取对象,不会去数据库校验,数据是否过期Customer customer11 =(Customer)session.get(Customer.class, 1);System.out.println(customer11);//query.list是也走一级缓存,但会校验,先得查询,然后flush一下,保证同步Customer customer12 =(Customer)session.createQuery("from Customer where id=1").uniqueResult();System.out.println(customer12);//显式的刷新session.flush();//刷出一级缓存,对比快照,发出update语句//隐式的刷新session.flush();session.getTransaction().commit();//flush和commit区别//flush作用是控制发出语句的,向数据库发sql的。//commit:本质:提交事务,只是,hierarnate隐式的flush了一下session.close();}
【提示】
flush和commit的区别:
l flush是发语句的。对比快照
l commit的是数据库层面的是否保存更改的数据(是否提交数据,是否持久化数据到数据库),若不手动发出flush, hibernate在commit之前自动先flush();
一级缓存的常用操作
一级缓存除了可以flush之外,还可以清除(clear,evict)、重载(reflesh)。
l flush:刷出一级缓存
作用:当一级缓存发生变化时,即和快照不同时,刷出一级缓存,会自动向数据库提交update语句。
如果是Mysql数据库,开启事务后,当手动flush后,不手动commit,Hibernate不会自动commit;
如果是Oracle数据库,开启事务后,当手动flush后,不手动commit,Hibernate自动commit(oracles事务的提交:手动提交、正常关闭连接的时候也会隐式提交);
l clear:清除一级缓存
作用:清除一级缓存中的所有对象,这些对象被清除后,会从持久态对象变成脱管态.
【扩展理解】
持久态对象与session关联的另一层含义就是对象在一级缓存中存在。
l evict:清除一级缓存指定对象
作用:清除一级缓存中的指定对象,使对象变成脱管态的。
l reflesh:刷新一级缓存
作用:刷新一级缓存中指定的对象,即发出SQL语句,
将对象重新放入一级缓存,并试图将数据库的数据同步到一级缓存中(同时更新一级缓存和快照),一级缓存之前的如果有修改将被覆盖掉。与flush有相反的感觉。
为什么要清除一级缓存:
大批量处理数据的时候,有些数据无需在一级缓存存在,或者已经处理完了,为了防止内存泄漏,一级缓存爆满,可以手动清除一级缓存的对象。
- hibernate学习笔记03----一级缓存
- hibernate学习笔记(session一级缓存)
- Hibernate学习笔记之session缓存(一级缓存)
- Hibernate学习笔记(三) — Hibernate 的一级缓存意义
- Hibernate学习-12:一级缓存
- hibernate学习之一级缓存
- Hibernate学习笔记:理解一级缓存和session清理
- hibernate学习笔记(一)之Junit 与 Session 一级缓存
- hibernate笔记04 hibernate一级缓存概述
- hibernate缓存学习之【一级缓存】
- hibernate缓存学习之【一级缓存】
- Mybatis学习笔记-一级缓存
- Hibernate学习:一级缓存和二级缓存
- Hibernate学习---第四节:一级缓存
- Hibernate一级缓存【Hibernate】
- hibernate学习笔记之三(一级缓存的使用和管理)
- Hibernate学习笔记之----理解对象的持久性与一级缓存机制
- hibernate3学习笔记(二)|一级缓存
- Idea项目如何迁移到Eclipse
- 如何使用 Android O 的自动填充框架
- android开源代码编译方法
- xgboost入门与实战(实战调参篇) 标签: xgboostpythonkaggle机器学习
- React.js笔记
- hibernate学习笔记03----一级缓存
- java 方法的重载和覆盖
- 链表的选择排序
- codevs 1183 泥泞的道路 (spfa +二分)
- 15. 3Sum
- linux下进程的创建和等待
- (LeetCode) 421. Maximum XOR of Two Numbers in an Array
- 多线程-线程概述等
- Notepad++配置Python开发环境