Hibernate[延迟加载] [三种状态] [脏检查] [缓存机制]
一、持久化对象的唯一标识
java中按内存地址不同区分同一个类的不同对象,关系数据库用主键区分同一条记录,Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系
什么是OID?
解析:OID是持久化与数据表主键对应属性,用来区分持久化对象
------------------------------------------------------------------------------------------------------------------------------------------------
二、主键生成策略
increment
identity
sequence
native
uuid
assigned
1) increment
由hibernate完成 主键递增,
原理:select max(id) , insert时max(id)+1 ,完成主键递增
优点:跨数据库
缺点:多线程并发访问问题(第一个线程执行成功,第二个线程报错)
2) identity
由底层数据库来完成自增 ,要求数据库必须支持自增主键 mysql支持 ,oracle不支持
3) sequence
编号列生成由底层数据库提供序列,来完成主键自增,要求数据库必须支持序列 mysql不支持,oracle支持
create sequence myseq; 创建序列
insert into customer values (myseq.nextval); 插入数据时调用序列,序列+1
4) native
采用数据库支持自增策略, mysql就用identity 、oracle就用sequence
策略1) ---> 策略4) 要求数据库主键必须为数字 ,因为只有数字才能自增
5) uuid
32位 唯一字符串, 主键使用varchar 类型
真实开发中,用程序提供uuid值
6) assigned
手动指定主键的值,该主键一般有实际意义,例如订单单号(20160114-A002)20160114-B001 20160114-C002。
复合主键,是一种特殊 assigned类型 自然主键 (通常需要手动指定),PO类必须实现Serializable接口
<class name="cn.happy.entity.Person" table="person">
<composite-id>
<key-property name="firstname"></key-property>
<key-property name="secondname"></key-property>
</composite-id>
</class>
7)foreign
使用另外一个相关联的对象的标识符。它通常和 <one-to-one>
联合起来使用。
8)hilo
使用一个高/低位算法高效的生成 long
,short
或者 int
类型的标识符。给定一个表和字段(默认分别是hibernate_unique_key
和 next_hi
)作为高位值的来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
9)select
通过数据库触发器选择一些唯一主键的行并返回主键值来分配一个主键。
三、延迟加载
延迟加载是Hibernate为提高程序执行效率而提供的一种机制,即只有真正需要数据的时候,才真正执行数据加载操作。
get()和load()区别:
① 在程序中提供的OID,对应的底层数据库没有编号.load()报错,get()得到null
② Load()没有使用对象的其他属性的时候,没有SQL 延迟加载
Get() :没有使用对象的其他属性的时候,也生成了SQL 立即加载
get()方法的执行顺序如下:
1 :首先通过id在session缓存中查找对象,如果存在此id的对象,直接将其返回
2:在二级缓存中查找,找到后将 其返回。
3 :如果在session缓存和二级缓存中都找不到此对象,则从数据库中加载有此ID的对象
因此get()方法并不总是导致SQL语句,只有缓存中无此数据时,才向数据库发送SQL!
是什么导致了延迟加载?
解析:因为内存中构建了代理对象
/*
* get
*/
@Test
public void getTest(){
Student stu=(Student)session.get(Student.class, );
System.out.println(stu);
} /*
* load
*/
@Test
public void loadTest(){
//直接返回的是代理对象
Student stu=(Student)session.load(Student.class, );
System.out.println(stu.getClass());
System.out.println(stu);
}
四、java对象的三种状态
持久态:
Student stu=new Student()
Session.save(stu);
Session以及数据库都有
游离态:
stu.setId(1);
Session.close();
Session没有 数据库中有
瞬时态:
Student stu=new Student()
体现:在Session中以及DB都没有
三种状态之间的转换:
该图从类型上划分为“活动图”
使用new关键字构建对象,该对象的状态是瞬时状态。
1 瞬时状态转为持久状态
使用Session对象的save()或saveOrUpdate()方法保存对象后,该对象的状态由瞬时状态转换为持久状态。
使用Session对象的get()或load()方法获取对象,该对象的状态是持久状态。
2 持久状态转为瞬时状态
执行Session对象的delete()方法后,对象由原来的持久状态变为瞬时状态,因为此时该对象没有与任何的数据库数据关联。
3 持久状态转为游离状态
执行了Session对象的evict()、clear()或close()方法,对象由原来的持久状态转为游离状态。
4 游离状态转为持久状态
重新获取Session对象,执行Session对象的update()或saveOrUpdate()方法,对象由游离状态转为持久状态,该对象再次与Session对象相关联。
5 游离状态转为瞬时状态
执行Session对象的delete()方法,对象由游离状态转为瞬时状态。
处于瞬时状态或游离状态的对象不再被其他对象引用时,会被Java虚拟机按照垃圾回收机制处理。
五、脏检查以及刷新缓存机制
Session到底是如何进行脏检查的呢?当一个Customer对象被加入到Session缓存中时,Session会为Customer对象的值类型的属性复制一份快照。当Session清理缓存时,会先进行脏检查,即比较Customer对象的当前属性与它的快照,来判断Customer对象的属性是否发生了变化,如果发生了变化,就称这个对象是“脏对象”,Session会根据脏对象的最新属性来执行相关的SQL语句,从而同步更新数据库。
Hibernate的一级缓存其实就是Session内置的一个Map,用来缓存它操作过的实体对象,对象的主关键字ID是Map的key,实体对
象就是对应的值。一级缓存是以实体对象为单位进行存储的,访问时也是以实体为单位的(直接访问属性是不能使用缓存的),并且要求使用主关键字ID来进行访问
六、Session<线程非安全>/SessionFactory<线程安全>
SessionFactoryImpl的源码。里面的实例变量大部分是final类型的,不可改变
SessionImpl的源码。大部分的实例变量是transient非final类型的。
Hibernate[延迟加载] [三种状态] [脏检查] [缓存机制]的更多相关文章
- hibernate的三种状态和缓存
hibernate的三种状态: 1.瞬时态:对象里面没有id值,对象与session没有关联 类似,把class类new出来,不存进session 2.持久态:对象里面有id值,对象与session关 ...
- Hibernate的三种状态及对象生命周期
理解Hibernate的三种状态,更利于理解Hibernate的运行机制,这些可以让你在开发中对疑点问题的定位产生关键性的帮助. 三种状态 临时状态(Transient):在通过new关键字, ...
- 第五讲:深入hibernate的三种状态
学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...
- [转]深入hibernate的三种状态
学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...
- 深入hibernate的三种状态
学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...
- 举例理解Hibernate的三种状态
初学Hibernate,了解到Hibernate有三种状态:transient(瞬时状态),persistent(持久化状态)以及detached(游离状态). 它们之间有如下转换图来说明: 1.tr ...
- 深入hibernate的三种状态(转)
hibernate的三种状态: 瞬时对象,持久化对象,托管对象. hibernate的两级缓存:1>一级缓存:session 2>二级缓存:sessionfactory. 瞬时对象: ...
- 【转】hibernate对象三种状态
hibernate里对象有三种状态: 1,Transient 瞬时 :对象刚new出来,还没设id,设了其他值. 2,Persistent 持久:调用了save().saveOrUpdate(),就变 ...
- hibernate的三种状态(儿)
第五讲:hibernate的三种状态 瞬时:bean对象与session,与数据库无关.在session对象的save方法保存之前. 持久状态(托管):bean对象与session有关,数据库中有对应 ...
随机推荐
- 使用stringstream格式化字符串
stringstream所在头文件为<sstream> 一般有如下常用功能: 1.安全格式化字符串 stringstream常用来安全的格式化若干个字符串,数值到一个缓冲区, 而不用担心溢 ...
- std::decay
参考资料 • cplusplus.com:http://www.cplusplus.com/reference/type_traits/decay/ • cppreference.com:http:/ ...
- python全栈开发从入门到放弃之内置函数
1.locals.globals def func(): x = 1 y = 2 print(locals()) #打印局部作用域中的名字 print(globals()) #打印全局作用域中的名字 ...
- Django:学习笔记(8)——视图
Django:学习笔记(8)——视图
- How can For each...
Answer: I understand the IEnumerator/IEnumerable methods and properties and also how they are inte ...
- 资料:mnist.pkl.gz数据包的下载以及数据内容解释
deeplearning.net/data/mnist/mnist.pkl.gz The MNIST dataset consists of handwritten digit images and ...
- Java并发编程:Lock(转)
本文转自:http://www.cnblogs.com/dolphin0520/p/3923167.html Java并发编程:Lock 在上一篇文章中我们讲到了如何使用关键字synchronized ...
- 使用selenium前学习HTML(2)——标签
<!-- HTML 标题(Heading)是通过 <h1> - <h6> 等标签进行定义的. HTML 段落是通过 <p> 标签进行定义的. HTML 链接是 ...
- ubuntu 14.04 163镜像
1.备份原来/etc/apt/sources.list 2.以下内容覆盖原来文件内容 deb http://mirrors.163.com/ubuntu/ trusty main restricted ...
- ViewResolver和ResponseBody笔记
处理HttpResponseBody有两种方式,ViewResolver(视图解析器)和ResponseBody ViewResolver.View多用于jsp,ViewResolver的主要作用是把 ...