Hibernate高级特性
2015-04-01 16:46
211 查看
Hibernate高级特性描述如下:
1.Hibernate持久化实现,细节包括:实体对象的生命周期,实体对象识别,数据缓存,事务管理以及持久层操作
2.Hibernate回调与拦截机制,细节包括:Lifecyle与Validatable接口 ,Hibernate Interceptor
①实体对象的声明周期
实体对象的三种状态,Transient状态(自由状态),Persistent(持久状态),Detached(游离状态)。当java new一个对象bean并赋值,这个bean只是一个自由状态的Object,它和数据库没有任何关系呢。当Hibernate操作该对象到数据库进行增删改查时,会先创建一个session即连接,这个session操作这个自由状态的Object后,这个Object就变成Persistent的了。所以持久状态的对象是和数据库有关系的,也是和session有关系的,它被Hibernate实体容器进行管理,
Persistent的对象,更改对象里的属性值,假定这个对象为 P1,然后session内操作另外一个Transient对象 T1,这时候P1更改后的值也会顺便更新到数据库里对应的记录上。因为Persistent的对象和数据库里的对象是有主键id对应关系的,自由状态的对象就没有这个对应关系。
当Session关闭后,持久状态的对象就变成游离状态的了。所以游离状态的对象是脱离了和Hibernate session的关系,但是还保留着和数据库的对应关系,因为有主键id对应关系。所以这时候如果创建一个新的session来操作这个游离对象,是直接可以操作数据库中对应记录的。
我们把Transient和Detached状态的对象叫做VO,把Persistent对象叫做PO,所以PO对象脱离session后就变成了VO。
②实体对象的身份识别
基本两个对象是否相等,根据两个对象是否对应数据库中同一条记录来判断,如果是,则相等。Hibernate对对象的相等判断做了封装。重新equals和hashcode方法。
③脏数据检查
脏数据检查一般有两种策略:
数据对象监控策略,大体上是通过拦截器对数据对象的设值方法(set)进行拦截,拦截器的实现可以通过DynamicProxy或者CgLib实现。
一旦数据对象的设置方法被调用,则将其设置为待更新状态,之后在数据库操作时,将它更新到对应的库表。
数据版本比较策略,在持久层框架中维持数据对象的最近读取版本,当数据提交时将提交数据与此版本进行比较,如果发生变化则将其同步到数据库对应的库表。
Hibernate采用数据版本比对的策略。
④数据缓存
数据缓存策略分为三种,事务级缓存,应用级/进程级缓存,分布式缓存。
事务级缓存是指事务范围内的,对于Hibernate来说,事务级缓存是基于Session生命周期实现的,每个Session会在内部维持一个数据缓存,此缓存随着Session的创建/销毁而存在/消亡,因此也成为Session Level Cache(内部缓存)。这个也就是一级缓存,可以通过Session.evict将某个特定对象从内部缓存清楚,通过Session.clear清空内部缓存。
应用级缓存,对于Hibernate来说,是在SessionFactory层实现的,所有由SessionFactory创建的Session实例共享此缓存,因此
也成为SessionFactory level cache。也就是二级缓存。
二级缓存使用前提条件:
数据不会被第三方应用修改(怕分布式应用影响),数据大小在可接受范围内,数据更新频率较低(不能频繁写),同一数据可能被系统频繁引用(缓存的目的),非关键数据(非金融数据对数据一致性要求特别高)。
分布式缓存,在多个应用实例之间,多个java之间共享的缓存模式。它是由多个应用级缓存实例组成集群,通过某种远程机制如
RMI或JMS实现各个缓存实例之间的数据同步,任何一个实例的数据修改操作,将导致整个集群之间的状态同步。开销大,使用需慎重。
第三方缓存:
Hibernate提供了面向第三方缓存实现的接口,如JCS,EHCache,OSCache,JBossCache,SwarmCache,其中后两个cache是支持分布式的。
Hibernate缓存内置的同步策略:
read-only,只读,对于不会发生改变的数据,可使用只读型缓存。
nonstrict-read-wirte .如果程序对并发访问下的数据同步要求不是非常严格,且数据更新操作频率较低(几个小时或者更长时间更新一次),可以使用本选项,获得较好的性能。
read-write。严格可读写缓存,基于时间戳判定机制,实现了‘read committed’事务隔离等级,但不支持分布式策略,这是实际中最常用的同步策略。
transactional,事务性缓存,必须运行在JTA事务环境中。事务缓存实现了‘Repeatable Read’事务隔离级别。目前Hibernate内置的cashe中,只有JbossCache支持事务性的Cache实现。
Hibernate四个事务特性,即ACID:
Atomic原子性,这里的原子代表事务中的各个操作不可分割。事务中包含的操作被看错一个逻辑单元,这个逻辑单元中的所有操作要么全部成功,要么全部失败。
Consistensy一致性,只有合法的数据才可以被写入数据库,如果数据有任何违例(比如数据与字段类型不符),则事务应该回滚到最初状态。
Isolation隔离性:事务允许多个用户对同一个数据的并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。事务隔离级别见下面相关内容。
Durability持久性:事务结束后,事务处理的结果必须能够得到固化(保存在硬盘上)
Hibernate事务隔离级别:
Default:默认数据库的隔离级别
Read Uncommitted
Read committed
Repeatable Read
Serializable。
Hibernate事务管理概述:
Hibernate是JDBC的轻量级封装,本身不具备事务管理能力,在事务管理层,Hibernate将其委托给低层的JDBC或JTA,以实现事务的管理和调度。具体封装代码和使用配置方法略。
Hibernate锁机制:
悲观锁:可以设置LOCK_MODE,设置悲观锁级别,比如无锁,读锁,写锁等
乐观锁:可以设置version方式,数据修改检测dirty data方式等,可以配置在xml文件中。
Hibernate持久层操作:
Session.get/load都是根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException
2.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。关于代理的内容可以参见稍后关于‘延迟加载’部分内容。
3.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找。如果没有发现对应数据,将越过二级缓存,直接调用sql完成数据读取。
批量查询方法有find/iterate两种,都是根据查询条件从数据库获取符合条件的记录,并返回对应的实体集。返回的集合类型是不同的,find返回list,iterate返回Iterator。find方法通过一条Select SQL实现了查询操作,而iterate方法则需要N+1次Sql,它首先
一次获取所有符合条件的记录的id,之后,再根据各个id从库表中读取对应的记录,典型的N+1次查询问题。那Iterator为啥存在呢?它其实主要是用于Hibernate二级缓存密切相关。find方法需要执行一次Select SQL以保证查询结果的完整性,iterate方法通过首先查询获取所有符合条件记录的id,以此保证查询结果的完整性。因此find方法实际上无法利用缓存,它对缓存只写不读。而iterate方法则可以充分发挥缓存带来的优势,如果目标数据只读或者读取相对较为频繁,通过这种机制可以大大减少性能上的损耗。
为了find一次读入内存数据过多,导致内存溢出,可以通过结合iterate方法和evict方法逐条对记录进行处理,将内存消耗保持在可接收范围之内。
QueryCache:
延迟加载 Lazy Loading:
具体包括实体对象的延迟加载,集合类的延迟加载,属性的延迟加载(属性值特别大,比如二进制大文本)等。
Hibernate增删改查方法,另外支持批量操作方法。比如批量删除,在执行批量删除之前会将所有符合条件的数据加载到内存中,如果数据量多大,就会导致OutOfMemoryError. 为了避免出现这类问题,可以变通的用 Session.iterate或者Query.iterate逐条获取数据,在执行delete操作。
Hibernate Collection:
Hibernate中涉及的Collection类型一共有以下几种:无序集,Set(里面不允许有重复元素),Bag(其实就是允许里面有重复元素的Set),Map。 有序集:List 。这些集合都是Hibernate自己提供的实现。
结果集排序方式有两种,Sort和order-by,sort操作是在jvm执行的,而order-by是由数据库完成的。Sort排序当然就是要排序的对象实现comparable接口。orderby就是修改数据库sql。Set,Map,Bag均支持order-by排序,有续集List例外。
Hibernate回调与拦截机制:
通过Lifecycle,Validatable接口制定了实体对象CRUD(增删改查)过程中的回调方式。
对于onSave,onUpdate,onDelete方法,如果返回true则意味着需要终止执行对应的操作过程,入股返回false则正常执行。如果抛出callbackException,对应操作也会被终止。而Validatable接口主要用于数据验证,验证不通过执行回调方法。
Lifecycle/validatable定义了一种自然的回调机制。
Interceptor:
Interceptor定义了Hibernate中通用拦截机制。Session创建的时候就能指定加载相应的Interceptor,此Session的持久化操作动作将首先经由此拦截器捕获处理。
Hibernate 实用技术:
Hibernate分页:
可以通过自带的Criteria.setFirstResult和Criteria.setFetchSize方法设定分页范围。
Hibernate与Spring整合使用:
内容较多,以后再描述。
Hibernate性能优化:
Hibernate的检测工具,和优化工具:
Hibernate Session管理:
Hibernate实战
1.Hibernate持久化实现,细节包括:实体对象的生命周期,实体对象识别,数据缓存,事务管理以及持久层操作
2.Hibernate回调与拦截机制,细节包括:Lifecyle与Validatable接口 ,Hibernate Interceptor
①实体对象的声明周期
实体对象的三种状态,Transient状态(自由状态),Persistent(持久状态),Detached(游离状态)。当java new一个对象bean并赋值,这个bean只是一个自由状态的Object,它和数据库没有任何关系呢。当Hibernate操作该对象到数据库进行增删改查时,会先创建一个session即连接,这个session操作这个自由状态的Object后,这个Object就变成Persistent的了。所以持久状态的对象是和数据库有关系的,也是和session有关系的,它被Hibernate实体容器进行管理,
Persistent的对象,更改对象里的属性值,假定这个对象为 P1,然后session内操作另外一个Transient对象 T1,这时候P1更改后的值也会顺便更新到数据库里对应的记录上。因为Persistent的对象和数据库里的对象是有主键id对应关系的,自由状态的对象就没有这个对应关系。
当Session关闭后,持久状态的对象就变成游离状态的了。所以游离状态的对象是脱离了和Hibernate session的关系,但是还保留着和数据库的对应关系,因为有主键id对应关系。所以这时候如果创建一个新的session来操作这个游离对象,是直接可以操作数据库中对应记录的。
我们把Transient和Detached状态的对象叫做VO,把Persistent对象叫做PO,所以PO对象脱离session后就变成了VO。
②实体对象的身份识别
基本两个对象是否相等,根据两个对象是否对应数据库中同一条记录来判断,如果是,则相等。Hibernate对对象的相等判断做了封装。重新equals和hashcode方法。
③脏数据检查
脏数据检查一般有两种策略:
数据对象监控策略,大体上是通过拦截器对数据对象的设值方法(set)进行拦截,拦截器的实现可以通过DynamicProxy或者CgLib实现。
一旦数据对象的设置方法被调用,则将其设置为待更新状态,之后在数据库操作时,将它更新到对应的库表。
数据版本比较策略,在持久层框架中维持数据对象的最近读取版本,当数据提交时将提交数据与此版本进行比较,如果发生变化则将其同步到数据库对应的库表。
Hibernate采用数据版本比对的策略。
④数据缓存
数据缓存策略分为三种,事务级缓存,应用级/进程级缓存,分布式缓存。
事务级缓存是指事务范围内的,对于Hibernate来说,事务级缓存是基于Session生命周期实现的,每个Session会在内部维持一个数据缓存,此缓存随着Session的创建/销毁而存在/消亡,因此也成为Session Level Cache(内部缓存)。这个也就是一级缓存,可以通过Session.evict将某个特定对象从内部缓存清楚,通过Session.clear清空内部缓存。
应用级缓存,对于Hibernate来说,是在SessionFactory层实现的,所有由SessionFactory创建的Session实例共享此缓存,因此
也成为SessionFactory level cache。也就是二级缓存。
二级缓存使用前提条件:
数据不会被第三方应用修改(怕分布式应用影响),数据大小在可接受范围内,数据更新频率较低(不能频繁写),同一数据可能被系统频繁引用(缓存的目的),非关键数据(非金融数据对数据一致性要求特别高)。
分布式缓存,在多个应用实例之间,多个java之间共享的缓存模式。它是由多个应用级缓存实例组成集群,通过某种远程机制如
RMI或JMS实现各个缓存实例之间的数据同步,任何一个实例的数据修改操作,将导致整个集群之间的状态同步。开销大,使用需慎重。
第三方缓存:
Hibernate提供了面向第三方缓存实现的接口,如JCS,EHCache,OSCache,JBossCache,SwarmCache,其中后两个cache是支持分布式的。
Hibernate缓存内置的同步策略:
read-only,只读,对于不会发生改变的数据,可使用只读型缓存。
nonstrict-read-wirte .如果程序对并发访问下的数据同步要求不是非常严格,且数据更新操作频率较低(几个小时或者更长时间更新一次),可以使用本选项,获得较好的性能。
read-write。严格可读写缓存,基于时间戳判定机制,实现了‘read committed’事务隔离等级,但不支持分布式策略,这是实际中最常用的同步策略。
transactional,事务性缓存,必须运行在JTA事务环境中。事务缓存实现了‘Repeatable Read’事务隔离级别。目前Hibernate内置的cashe中,只有JbossCache支持事务性的Cache实现。
Hibernate四个事务特性,即ACID:
Atomic原子性,这里的原子代表事务中的各个操作不可分割。事务中包含的操作被看错一个逻辑单元,这个逻辑单元中的所有操作要么全部成功,要么全部失败。
Consistensy一致性,只有合法的数据才可以被写入数据库,如果数据有任何违例(比如数据与字段类型不符),则事务应该回滚到最初状态。
Isolation隔离性:事务允许多个用户对同一个数据的并发访问,而不破坏数据的正确性和完整性。同时,并行事务的修改必须与其他并行事务的修改相互独立。事务隔离级别见下面相关内容。
Durability持久性:事务结束后,事务处理的结果必须能够得到固化(保存在硬盘上)
Hibernate事务隔离级别:
Default:默认数据库的隔离级别
Read Uncommitted
Read committed
Repeatable Read
Serializable。
Hibernate事务管理概述:
Hibernate是JDBC的轻量级封装,本身不具备事务管理能力,在事务管理层,Hibernate将其委托给低层的JDBC或JTA,以实现事务的管理和调度。具体封装代码和使用配置方法略。
Hibernate锁机制:
悲观锁:可以设置LOCK_MODE,设置悲观锁级别,比如无锁,读锁,写锁等
乐观锁:可以设置version方式,数据修改检测dirty data方式等,可以配置在xml文件中。
Hibernate持久层操作:
Session.get/load都是根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
1.如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException
2.Load方法可返回实体的代理类实例,而get方法永远直接返回实体类。关于代理的内容可以参见稍后关于‘延迟加载’部分内容。
3.load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找。如果没有发现对应数据,将越过二级缓存,直接调用sql完成数据读取。
批量查询方法有find/iterate两种,都是根据查询条件从数据库获取符合条件的记录,并返回对应的实体集。返回的集合类型是不同的,find返回list,iterate返回Iterator。find方法通过一条Select SQL实现了查询操作,而iterate方法则需要N+1次Sql,它首先
一次获取所有符合条件的记录的id,之后,再根据各个id从库表中读取对应的记录,典型的N+1次查询问题。那Iterator为啥存在呢?它其实主要是用于Hibernate二级缓存密切相关。find方法需要执行一次Select SQL以保证查询结果的完整性,iterate方法通过首先查询获取所有符合条件记录的id,以此保证查询结果的完整性。因此find方法实际上无法利用缓存,它对缓存只写不读。而iterate方法则可以充分发挥缓存带来的优势,如果目标数据只读或者读取相对较为频繁,通过这种机制可以大大减少性能上的损耗。
为了find一次读入内存数据过多,导致内存溢出,可以通过结合iterate方法和evict方法逐条对记录进行处理,将内存消耗保持在可接收范围之内。
QueryCache:
延迟加载 Lazy Loading:
具体包括实体对象的延迟加载,集合类的延迟加载,属性的延迟加载(属性值特别大,比如二进制大文本)等。
Hibernate增删改查方法,另外支持批量操作方法。比如批量删除,在执行批量删除之前会将所有符合条件的数据加载到内存中,如果数据量多大,就会导致OutOfMemoryError. 为了避免出现这类问题,可以变通的用 Session.iterate或者Query.iterate逐条获取数据,在执行delete操作。
Hibernate Collection:
Hibernate中涉及的Collection类型一共有以下几种:无序集,Set(里面不允许有重复元素),Bag(其实就是允许里面有重复元素的Set),Map。 有序集:List 。这些集合都是Hibernate自己提供的实现。
结果集排序方式有两种,Sort和order-by,sort操作是在jvm执行的,而order-by是由数据库完成的。Sort排序当然就是要排序的对象实现comparable接口。orderby就是修改数据库sql。Set,Map,Bag均支持order-by排序,有续集List例外。
Hibernate回调与拦截机制:
通过Lifecycle,Validatable接口制定了实体对象CRUD(增删改查)过程中的回调方式。
对于onSave,onUpdate,onDelete方法,如果返回true则意味着需要终止执行对应的操作过程,入股返回false则正常执行。如果抛出callbackException,对应操作也会被终止。而Validatable接口主要用于数据验证,验证不通过执行回调方法。
Lifecycle/validatable定义了一种自然的回调机制。
Interceptor:
Interceptor定义了Hibernate中通用拦截机制。Session创建的时候就能指定加载相应的Interceptor,此Session的持久化操作动作将首先经由此拦截器捕获处理。
Hibernate 实用技术:
Hibernate分页:
可以通过自带的Criteria.setFirstResult和Criteria.setFetchSize方法设定分页范围。
Hibernate与Spring整合使用:
内容较多,以后再描述。
Hibernate性能优化:
Hibernate的检测工具,和优化工具:
Hibernate Session管理:
Hibernate实战
相关文章推荐
- Hibernate高级特性以及性能优化
- Hibernate高级特性的随堂笔记
- Hibernate3高级特性-使用过滤器
- Hibernate基本特性和高级特性
- Hibernate中的高级特性
- Hibernate关联操作、查询操作、高级特性、并发处理机制
- 全面解析Hibernate关联操作、查询操作、高级特性、并发处理机制
- Hibernate学习笔记之高级特性
- 'Hibernate 完全手册' 读书笔记(五) 事务和并发、缓存、高级特性、附录
- Hibernate3高级特性-使用过滤器
- Hibernate一些高级特性
- JavaSE复习之十五 高级特性:数据库及数据库连接
- JavaScript中的高级特性及特别对象、属性和方法
- Hibernate事务的高级应用
- JavaSE复习之十一 高级特性:反射和注释 补充(1)
- 用路由系统生成输出URL 在视图中生成输出URL 高级路由特性 精通ASP-NET-MVC-5-弗瑞曼
- Python 高级特性之列表生成式
- Hibernate高级查询方法
- 高级特性(20160811).md
- python高级特性(4):生成器