`
forever1121
  • 浏览: 16530 次
  • 性别: Icon_minigender_2
  • 来自: 齐齐哈尔
社区版块
存档分类
最新评论

Hibernate_11

阅读更多
缓存的物理介质通常是内存,而永久性数据存储源的物理介质通常是硬盘和磁盘,应用程序读写内存的速度显然比读写硬盘的速度快。若缓存中存放的数据量非常大,也会用硬盘作为缓存的物理介质。缓存的实现不仅需要作为物理介质的硬件,同时还需要用于管理缓存的并发访问和过期等策略的软件。
SessionFactory的缓存可分为两类:内置缓存和外置缓存。SessionFactory的内置缓存是Hibernate自带的,不可卸载。通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义SQL语句存放到SessionFactory的内置缓存中,映射元数据是映射文件中数据的复制,而预定义SQL语句是Hibernate根据映射元数据推导出来的。SessionFactory的内置缓存是只读缓存,应用程序不能修改换成那种的映射元数据和预定义的SQL语句。因此SessionFactory无需进行内置缓存与映射文件的同步。SessionFactory的外置缓存是一个可配置的缓存插件。在默认的情况下,SessionFactory不会启用这个缓存插件。外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或硬盘。
Hibernate的Session缓存中存放的数据是数据库中的数据的复制。在数据库中数据表现为关系数据形式,而在Session缓存中表现为相互关联的对象。在读写数据库时,Session会负责这种形式的数据映射。Session会在某些时间点会按照缓存中的数据来同步更新数据库,这一过程被称为清理缓存。

缓存的范围可以分为三类:事务范围、进程范围和集群范围。
事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束,缓存也就结束生命周期。缓存的物理介质为内存。每个事务都有独自的缓存,缓存内的数据通常采用相互关联的对象形式。在同一个事务中,持久化类的每个对象具有唯一的OID。
进程范围:缓存被进程内的所有事务共享。这些事务有可能并发访问缓存,因此,必须对缓存采取必要的事务隔离机制。缓存的生命周期依赖与进程的生命周期,当进程结束,缓存也就结束生命周期。进程范围的缓存可能会存放大量数据,它的物理介质可以是内存或硬盘。缓存内的数据既可以采用相互关联的对象模式,也可采用对象的散装数据形式。对象的散装数据有点类似于对象的序列化数据,但是把对象分解为散装数据的算法通常比对象的序列化的算法更快。
集群范围:在集群环境中,缓存被同一个机器或多个机器上的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程之间通过远程通信来保证缓存中数据的一致性,缓存中的数据通常采用对象的散装数据形式。

进程范围或集群范围缓存,即第二级缓存,会出现并发问题。对第二级缓存可以设定以下4种类型的并发访问策略,每一种策略对应一种事务隔离级别。
事务型(Transactional):仅在受管理环境中适用。它提供Repeatable Read事务隔离级别。对于经常被读但是很少被修改的数据,可以采用这种隔离类型。可以防止脏读和不可重复读。
读写型(Read-write):提供Read Committed事务隔离级别。仅在非集群的环境中适用。对于经常被读但是很少被修改的数据,可以采用这种隔离类型。可以防止脏读这类并发问题。
非严格读写型(Nonstrict-read-write):不保证缓存与数据库中数据的一致性。若存在两个事务同时访问缓存中相同数据的可能,必须为该数据配置一个很短的数据过期时间,从而尽量避免脏读。对于极少被更改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。
只读型(Read-only):对于从来不会被修改的数据,若参考数据,可以使用这种并发访问策略。
符合以下条件的数据适合存放到第二级缓存:
很少被修改的数据
不是很重要的数据,允许出现偶尔的并发问题
不会被并发访问的数据
参考数据
参考数据是指供应用参考的常量数据,有以下几个特点:他的实例的数目有限、每个实例会被许多其他类的实例引用、它的实例极少或者从来不会被修改。

缓存配置器(Cache Provider)用于把具体的缓存实现软件与Hibernate集成。

当应用程序调用Session的save()、update()、saveOrUpdate()、load()和get()方法及调用Query查询接口的list()、iterate()和filter()方法时,若在Session的缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。
Session为应用程序提供了两个管理缓存的方法:
evict(Object o):从缓存中清楚参数指定的持久化对象
clear():清空缓存中所有持久化对象
Session的evict()方法能够从缓存中清除特定的持久化对象,适用于一下情况:
不希望Session继续按照该对象的状态变化来同步更新数据库。
在批量更新或批量删除的场合,当更新或删除一个对象后,及时释放该对象占用的内存。

Hibernate的第二级缓存是进程或集群范围内的缓存,缓存中存放的是对象的散装数据。第二级缓存是可配置的插件,Hibernate允许选用以下类型的缓存插件:
EHCache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,对Hibernate的查询缓存提供了支持。
OpenSymphonyOSCache:可作为进程范围内的缓存,存放数据的物理介质可以是内存或硬盘,提供了更夫的缓存数据过期策略,对Hibernate的查询缓存提供了支持。
SwarmCache:可作为集群范围内的缓存,但不支持Hibernate的查询缓存。
JBossCache:可作为集群范围内的缓存,支持事务性并发访问策略,对Hibernate的查询缓存提供了支持。
                  各个缓存插件支持的并发访问策略
缓存插件                 只读型     非严格读写型      读写型      事务型
EHCache                    支持         支持          支持         否
OpenSymphonyOSCache        支持         支持          支持         否
SwarnCache                 支持         支持          否           否
JBossCache                 支持         否            否           否
为了把这些缓存插件集成到Hibernate中,Hibernate提供了org.hibernate.cacha.CacheProvider接口,它是缓存插件与Hibernate之间的适配器。Hibernate为以上缓存插件分别提供了内置的CacheProvider实现:
org.hibernate.cache.EhCacheProvider:EHCache插件的适配器
org.hibernate.cache.OSCacheProvider:OSCacheProvider插件的适配器
org.hibernate.cache.SwarmCacheProvider:SwarmCache插件的适配器
org.hibernate.cache.TreeCacheProvider:TreeCacheProvider插件的适配器

配置第二级缓存主要包含一下几个步骤:
1.选择需要使用第二级缓存的持久化类,设置它的第二级缓存的并发访问策略。Hibernate既允许在分散的各个映射文件中为持久化类设置第二级缓存,还允许在Hibernate的配置文件hibernate.cfg.xml中集中设置第二级缓存,后一种方式更有利于对于缓存相关的配置代码的维护。
2.选择合适的缓存插件,每一种缓存插件都有自带的配置文件,需要手动编辑该配置文件。EHCache缓存的配置文件为ehcache.xml,而JBossCache缓存的配置文件为treecache.xml。

Hibernate允许在类和集合的粒度上设置第二级缓存。在映射文件中,<class>和<set>元素下都有一个<cache>子元素,这个子元素用来配置第二级缓存。
<cache  usage="transactional | read-write| nonstrict-read-write| read-only"   //必须的  指定并发访问策略
        region="RegionName"   //可选的  指定第二级缓存的区域的名字。默认值为类或集合的名字
        include="all| non-lazy" />   //可选的  是否加载延迟对象  默认为all
<cache>元素的属性
name:设置缓存的名字,取值为类的完整名字或者类的集合的名字
maxInMemory:设置基于内存的缓存可存放的对象的最大数目
eternal:若为true,表示对象永远不会过期,默认为false
timeToIdelSeconds:允许对象处于空闲状态的最长时间,以秒为单位。
timeToLiveSeconds:允许对象存在于缓存中的最长时间。
overflowToDisk:若为true,表示当基于内存的缓存中的对象数目达到了maxInMemory界限,会把溢出的对象写到基于硬盘的缓存中。

EHCache适用于Hibernate应用发布在单个机器的场合。若要把应用发布到多台机器中,可以用JBossCache作为Hibernate的第二级缓存。
1.在Hibernate配置文件中设置JBossCache适配器,并且为需要使用的第二级缓存的类和集合设置缓存的并发访问策略。
2.编辑JBossCache自身的配置文件,名为treecache.xml。这个文件必须存放于应用的classpath中。对于集群环境中的每个节点,都必须提供单独的

treecache.xml文件。

SessionFactory的evict()方法用于清除对象的散装数据,SessionFactory的getStatistics()方法用于查看第二级缓存中的数据:
Map cacheEntries = sessionFactory.getStatistics().getSecondLevelCacheStatistics(regionName).getEntries();

Session与第二级缓存交互有5种模式,分别用org.hibernate.CacheMode类的5个静态常量来表示:
CacheMode.NORMAL:正常模式(默认),Session会从第二级缓存中读取数据,也会向其中写入数据
CacheMode.IGNORAL:忽略模式,Session不会从第二级缓存中读取数据,也不会向其中写入数据
CacheMode.GET:读取模式,Session会从第二级缓存中读取数据,但不会向其中写入数据
CacheMode.PUT:写入模式,Session不会从第二级缓存中读取数据,但会向其中写入数据
CacheMode.REFRESH:刷新模式,Session不会从第二级缓存中读取数据,但会向其中写入数据。与PUT的区别是:REFRESH会忽略Hibernate配置文件中的

hibernate.cache.use_minimal_puts属性,强制刷新第二级缓存中的所有数据。

Hibernate提供了3种管理Session对象的方法:
1.Session对象的生命周期与本地线程绑定
2.Session对象的生命周期与JTA事务绑定
3.Hibernate委托程序管理Session对象的生命周期

在Hibernate的配置文件中,hibernate.current_session_context_class属性用于指定Session管理方式,可选值包括:thread:Session对象的生命周期与本地线程绑定;jta:Session的生命周期与JTA事务绑定;managed:Hibernate委托程序来管理Session对象的生命周期。

Hibernate按照以下规则把Session与本地线程绑定:
当一个线程A第一次调用SessionFactory对象的getCurrentSession()方法时,该方法会创建一个新的Session对象,把它与线程A绑定,并将SessionA对象返回。
接下来,当线程A再次调用SessionFactory对象的getCurrentSession()方法时,该方法始终返回SessionA对象。
当线程A提交与SessionA对象关联的事务时,Hibernate会自动清理SessionA对象的缓存,然后在提交事务后,关闭SessionA对象。此外,若当线程A撤销与SessionA对象关联的事务时,也会自动关闭SessionA对象。
若线程A再次调用SessionFactory对象的getCurrentSession()方法时,该方法又会创建一个新的Session对象,把它与线程A绑定。

Hibernate按照以下规则把Session与JTA绑定:
程序先通过UserTransaction接口声明开始一个JTA事务。接下来当程序第一次调用SessionFactory对象的getCurrentSession()方法时,该方法会创建一个新的Session对象,把它与当前的JTA事务绑定,并将SessionA对象返回。
接下来,当程序多次调用SessionFactory对象的getCurrentSession()方法时,该方法始终返回与当前JTA事务绑定的SessionA对象。
当程序提交当前JTA事务时,Hibernate会自动清理SessionA对象的缓存,然后在事务提交后,关闭SessionA对象。此外,若当程序撤销当前JTA事务时,也会自动关闭SessionA对象。

Hibernate提供两种实现对话的方式:
使用游离对象:一个对话包括多个短事务,并且每个短事务对应一个Session对象。事务之间通过游离对象传递业务数据
使用手工清理缓存模式下的Session对象:一个对话包括多个短事务,并且整个对话对应一个Session对象

采用手工清理缓存模式下的Session,整个对话由多个短事务构成,并且整个对话对应一个Session对象,这个Session对象的生命周期由程序自主管理。程序处理的主要流程如下:
创建完Session对象后,立即调用session.setFlushMode(FlushMode.MANUAL)方法,把缓存模式设为手工清理模式。
在手工清理模式下,当程序声明提交事务时,Hibernate不会自动清理缓存,因此不会同步更新数据库,不过,Hibernate会自动释放Session对象占用的数据库连接。
当程序声明开始事务时,假如当前Session对象不占用数据库连接,Hibernate会自动为它分配数据库连接
只有当对话块结束,在提交最后一个事务之前,程序需要调用session.flush()方法手工清理缓存,根据缓存中对象的变化去同步更新数据库。

在手工清理Session缓存的模式下,至哟当程序调用Session的flush()方法时才会清理缓存。但通过Session的save()方法执行插入操作时,若对象标识符OID生成策略为identity或select,那么save()方法会立即向数据库插入数据,然后生成对象标识符。

Hibernate委托程序来管理Session:
把Hibernate配置文件的hibernate.current_session_context_class属性设为managed。
当程序创建Session对象后或声明开始一个事务前,调用org.hibernate.context.ManagedContext类的bind()方法,该方法把Session对象与当前线程绑定。
在一个事务中,程序可通过SessionFactory的getCurrentSession()方法来获得当前Session对象。
当程序提交对话中的一个事务之前,调用org.hibernate.context.ManagedSessionContext类的unbind()方法,该方法解除当前Session对象与当前线程的绑定。

org.hibernate.context.ManagedSessionContext类提供了一下静态方法:
bind(Session session):把Session和当前线程绑定
unbind(SessionFactory factory):解除Session对象与当前的绑定
hasBind(SessionFactory factory):判断是否存在与当前线程绑定的Session对象。


本来想今天下午把Hibernate全部整理完的,结果今天不知抽了什么风,颈椎酸疼,四肢无力,还恶心想吐...真是的,才工作一个月就有颈椎病,这以后还怎么继续愉快的玩耍...真是郁闷............
分享到:
评论

相关推荐

    hibernate_day02笔记

    【hibernate_day02笔记】的文档主要涵盖了学习Hibernate框架的基础内容,包括ORM思想、Hibernate入门案例、配置文件解析、核心API的使用等。以下是详细的讲解: **ORM思想**: ORM(Object-Relational Mapping)即...

    hibernate_persistence第02-16章书中源码

    6. **hibernate_11_001_MyDefinitionUserType** 和 **hibernate_11_002_MyDefinitionType_BKBLX**: 这些章节可能涉及到自定义类型。在Hibernate中,你可以通过实现UserType接口来自定义数据类型的映射,使非标准的...

    hibernate_day03笔记

    hibernate_day03笔记

    hibernate_cache_level_1

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者用面向对象的方式处理数据库操作。在大型应用中,为了提高性能,有效地管理数据访问,Hibernate引入了缓存机制。本篇文章将深入探讨...

    Hibernate_Tools_for_Eclipse插件的安装和使用

    Hibernate_Tools_for_Eclipse插件的安装和使用 Hibernate_Tools_for_Eclipse插件是 Eclipse 中的一个插件,用于支持 Hibernate 开发。它提供了许多有用的功能,如Hibernate配置文件的创建、实体类的生成、SQL语句...

    hibernate_day04笔记

    hibernate_day04笔记

    DMS.rar_dms_hibernate_myeclipse hibernate_mysql hibernate_struts

    标题"DMS.rar_dms_hibernate_myeclipse hibernate_mysql hibernate_struts"表明这是一个与数据库管理系统(DMS)相关的项目,使用了Hibernate ORM框架,MyEclipse作为开发环境,并结合了MySQL数据库和Struts框架。...

    Hibernate_QBC和Hibernate_QBE

    标题"Hibernate_QBC和Hibernate_QBE"提及了两个关于Hibernate的查询方式,即Query By Criteria(QBC)和Query By Example(QBE)。Hibernate是Java领域中一个广泛使用的对象关系映射(ORM)框架,它允许开发者以面向...

    java_hibernate_day01.pdf

    java_hibernate_day01.pdf

    java_hibernate_day02.pdf

    java_hibernate_day02.pdf

    Hibernate_3.2.0_Reference_zh_CN.rar hibernate中文api

    11. **Criteria与HQL的比较**:两者都是ORM查询方式,HQL更接近SQL,适合复杂的查询;Criteria则更面向对象,方便代码维护。 12. **集合映射**:通过`@OneToMany`、`@ManyToOne`、`@OneToOne`、`@ManyToMany`等注解...

    hibernate_second2项目源码

    【hibernate_second2项目源码】是一个基于Hibernate框架的示例项目,它在前一个项目的基础上进行了扩展,特别引入了级联保存的功能。在这个项目中,我们将深入探讨Hibernate的级联操作,以及如何实现数据的级联保存...

    hibernate_day4_hibernate_sick7s3_

    【标题】"hibernate_day4_hibernate_sick7s3_" 暗示这是一个关于Hibernate框架的学习资源,可能是第四天的学习内容,专注于"hibernate_sick7s3"这个特定主题。在这个主题下,可能涉及了更深入或者特别的使用场景或...

    struts_hibernate_bbs.rar_bbs_hibernate b_hibernate bbs_struts hi

    Struts和Hibernate是Java开发中两个非常重要的框架,它们在构建Web应用程序,特别是大型的、数据驱动的BBS(Bulletin Board System,论坛)系统时,起到了核心作用。本压缩包"struts_hibernate_bbs.rar"包含了一个...

    Hibernate_3.2.0_Reference_zh_CN

    11. **关联映射**:包括一对一、一对多、多对一、多对多等各种关联类型,以及懒加载和立即加载策略。 12. **集合映射**:讲解了如何将Java集合类如List、Set和Map映射到数据库表的行。 13. **性能优化**:提供了...

    test_hibernate_oracle_03.zip_Insert _hibernate_oracle_query_upda

    【标题】"test_hibernate_oracle_03.zip"是一个包含使用Hibernate框架与Oracle数据库进行CRUD操作(创建、读取、更新、删除)的示例项目。这个压缩包提供了有关如何通过Hibernate在Oracle数据库中执行插入、查询、...

    MyEclipse_Hibernate_Quickstart

    ### MyEclipse与Hibernate快速入门知识点详解 #### 一、前言 本篇文章将详细介绍如何使用MyEclipse Enterprise Workbench进行Hibernate开发的基础特征、概念和技术。通过构建一个简单的Java Hibernate应用来逐步...

    JavaEE源代码 Hibernate_Spring

    JavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_SpringJavaEE源代码 Hibernate_...

    JavaEE源代码 Hibernate_mapping

    JavaEE源代码 Hibernate_mappingJavaEE源代码 Hibernate_mappingJavaEE源代码 Hibernate_mappingJavaEE源代码 Hibernate_mappingJavaEE源代码 Hibernate_mappingJavaEE源代码 Hibernate_mappingJavaEE源代码 ...

Global site tag (gtag.js) - Google Analytics