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

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. CSS Hack解决浏览器IE部分属性兼容性问题

    1.Css Hack 不同厂商的流览器或某浏览器的不同版本(如IE6-IE11,Firefox/Safari/Opera/Chrome等),对CSS的支持.解析不一样,导致在不同浏览器的环境中呈现出不 ...

  2. 轻量的、可自定义 CSS 的 Lightbox 相册插件

    jQuery LightGallery是一个轻量级的,可定制的,模块化的,响应式的 jQuery 相册插件.它采用 CSS 来实现图像和视频的大小调整.因此,这将是非常灵活的,并且比使用 JavaSc ...

  3. css3之3d导航

    css3的新属性非常不错,目前IE除外其他浏览器都已支持 实现原理:比如元素a在hover时候可以改变元素b的状态. 效果如本农导航,欢迎采用和建议~ a:hover b{ 执行简单动画效果 } HT ...

  4. vs2012使用64位IIS EXPRESS调试

    使用Visual Studio 2012开发网站或web应用程序时,可以使用两种web server.自带的development server和IIS EXPRESS.development ser ...

  5. #9.1课堂总结#JS基础(二)

    在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只 ...

  6. webpack CommonsChunkPlugin详细教程

    1.demo结构: 2.package.json配置: { "name": "webpack-simple-demo", "version" ...

  7. Googlehack之Github hack

    site:aircrk.com smtpsite:aircrk.com smtp @mail.comsite:aircrk.com root passwordsite:aircrk.com smtp ...

  8. Sharepoint学习笔记—习题系列--70-576习题解析 --索引目录

        Sharepoint学习笔记—习题系列--70-576习题解析  为便于查阅,这里整理并列出了70-576习题解析系列的所有问题,有些内容可能会在以后更新. 需要事先申明的是:     1. ...

  9. 二进制配置文件为什么比json等配置文件效率高

    二进制配置文件为什么比json等配置文件高效 项目中用spine做动画,spine可以导出json和二进制的动画配置文件,蛋疼的是spine官方竟然没有提供c的二进制配置解析代码,更没有提供它二进制文 ...

  10. cocos2dx骨骼动画Armature源码分析(三)

    代码目录结构 cocos2dx里骨骼动画代码在cocos -> editor-support -> cocostudio文件夹中,win下通过筛选器,文件结构如下.(mac下没有分,是整个 ...