一、持久化对象的唯一标识

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

使用一个高/低位算法高效的生成 longshort 或者 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, 12);
System.out.println(stu);
} /*
* load
*/
@Test
public void loadTest(){
//直接返回的是代理对象
Student stu=(Student)session.load(Student.class, 12);
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延迟加载、三种状态、脏检查 缓存的更多相关文章

  1. Hibernate[延迟加载] [三种状态] [脏检查] [缓存机制]

    一.持久化对象的唯一标识 java中按内存地址不同区分同一个类的不同对象,关系数据库用主键区分同一条记录,Hibernate使用OID来建立内存中的对象和数据库中记录的对应关系 什么是OID? 解析: ...

  2. hibernate的三种状态和缓存

    hibernate的三种状态: 1.瞬时态:对象里面没有id值,对象与session没有关联 类似,把class类new出来,不存进session 2.持久态:对象里面有id值,对象与session关 ...

  3. Hibernate的三种状态及对象生命周期

        理解Hibernate的三种状态,更利于理解Hibernate的运行机制,这些可以让你在开发中对疑点问题的定位产生关键性的帮助. 三种状态 临时状态(Transient):在通过new关键字, ...

  4. 第五讲:深入hibernate的三种状态

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  5. [转]深入hibernate的三种状态

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  6. 深入hibernate的三种状态

    学过hibernate的人都可能都知道hibernate有三种状态,transient(瞬时状态),persistent(持久化状态)以及detached(离线状态),大家伙也许也知道这三者之间的区别 ...

  7. 举例理解Hibernate的三种状态

    初学Hibernate,了解到Hibernate有三种状态:transient(瞬时状态),persistent(持久化状态)以及detached(游离状态). 它们之间有如下转换图来说明: 1.tr ...

  8. 深入hibernate的三种状态(转)

    hibernate的三种状态: 瞬时对象,持久化对象,托管对象. hibernate的两级缓存:1>一级缓存:session    2>二级缓存:sessionfactory. 瞬时对象: ...

  9. 【转】hibernate对象三种状态

    hibernate里对象有三种状态: 1,Transient 瞬时 :对象刚new出来,还没设id,设了其他值. 2,Persistent 持久:调用了save().saveOrUpdate(),就变 ...

  10. hibernate的三种状态(儿)

    第五讲:hibernate的三种状态 瞬时:bean对象与session,与数据库无关.在session对象的save方法保存之前. 持久状态(托管):bean对象与session有关,数据库中有对应 ...

随机推荐

  1. HotCode的原理及使用

    1. JRbel介绍 JRebel是一套JavaEE开发工具.Jrebel可快速实现热部署,节省了大量重启时间,提高了个人开发效率.网上可搜索到破解版.JRebel是一款JAVA虚拟机插件,它使得JA ...

  2. Verilog学习笔记基本语法篇(十一)········ 常用系统函数

    1)系统任务:$monitor   格式: $monitor(p1,p2,p3...pn); $monitor; $monitoron; $monitoroff; 任务$monitor提供了监控输出列 ...

  3. 解决Visual C++ Redistributable for Visual Studio 2015的安装问题

    1. Visual C++ Redistributable for Visual Studio 2015系统要求:Windows 7情况下必须是Windows 7 with SP1.或者Windows ...

  4. OData V4 系列 .net应用

    OData 学习目录 添加 OData Client Code Generator 扩展 添加OData T4生成工具 修改 T4 模板的 MetadataDocumentUri 运行Web项目,之后 ...

  5. javascript移动设备Web开发中对touch事件的封装实例

    在触屏设备上,一些比较基础的手势都需要通过对 touch 事件进行二次封装才能实现.zepto 是移动端上使用率比较高的一个类库,但是其 touch 模块模拟出来的一些事件存在一些兼容性问题,如 ta ...

  6. [Javascript]利用当前时间生成yyyymmddhhmmss这样的字符串

    function pad2(n) { return n < 10 ? '0' + n : n } function generateTimeReqestNumber() { var date = ...

  7. OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

    OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...

  8. 移动端rem布局实践

      一.rem 适配基本概念: 对于移动端的开发,rem 适配必不可少,我们可以用多种方式实现, 根据 html 的 fontSize 属性值为基准,其它所有的 rem 值,根据这个基准计算.我们根据 ...

  9. RunLoop-Custom input source

    Creating Creating a custom input source involves defining the following: The information you want yo ...

  10. WinHEC 2015 深圳之行

    在上个月,本人有幸在MVP Team和MVP Lead的帮助下,参加了微软在深圳召开的WinHEC 2015大会. 在本次大会上,见证了微软和国内企业的合作,并且发布一些关于在Windows 10方面 ...