Hibernate5.0用户手册中文版

上传人:阳*** 文档编号:35033817 上传时间:2021-10-25 格式:DOCX 页数:231 大小:287.93KB
收藏 版权申诉 举报 下载
Hibernate5.0用户手册中文版_第1页
第1页 / 共231页
Hibernate5.0用户手册中文版_第2页
第2页 / 共231页
Hibernate5.0用户手册中文版_第3页
第3页 / 共231页
资源描述:

《Hibernate5.0用户手册中文版》由会员分享,可在线阅读,更多相关《Hibernate5.0用户手册中文版(231页珍藏版)》请在装配图网上搜索。

1、Hibernate.org社区文档Hibernate 用户手册Hibernate - 纯java的关系型持久层框 Hibernate 团队JBoss 可视化设计团队 5.0.0.FinalCopyright 2011 Red Hat, Inc.2015-08-20目录Hibernate 用户手册1Hibernate - 纯java的关系型持久层框1Hibernate 团队1JBoss 可视化设计团队1序言8第章.Architecture(体系架构)91.1.概述101.2.Contextual sessions(session上下文)11第2章.Domain Model(域模型)122.1.P

2、OJO 模型132.1.1.实现无参构造函数132.1.2.提供identifier(标识)属性142.1.3.使用非final类142.1.4.为持久化属性声明 get,set方法152.1.5.实现 equals()与hashCode()方法152.2.Dynamic(动态)模型23第3章Bootstrap(引导、启动253.1. Native (原生、本地)引导263.1.1.构建ServiceRegistry263.1.2.构建Metadata293.1.3.构建SessionFactory323.2.JPA引导 JPA Bootstrapping343.2.1.JPA兼容模式的引导3

3、43.2.2. Proprietary 2-phase引导35第4章持久化Context(上下文)354.1.实体持久化364.2.删除实体374.3.获取没有初始化数据的实体384.4.获取已经初始化数据的实体384.5.通过natural-id(自然ID)获得实体394.6.刷新实体状态414.7.更改托管态或者持久态424.8.使用游离态数据424.8.1.复位游离态数据(游离态变成托管态)434.8.2.合并游离态数据 4.9.验证对象的状态444.10.从JPA访问Hibernate46第5章访问数据库465.1.ConnectionProvider(连接提供器)475.1.1.使用

4、DataSources485.1.2. 使用c3p0485.1.3.使用proxool连接池505.1.4.使用Hikari515.1.5.使用Hibernate内置的(不支持)的连接池515.1.6.用户自定义的连接525.1.7. ConnectionProvider事务设置525.2.数据库Dialect(方言)52第6章事务与并发控制546.1.物理事务556.1.1.JTA配置566.2.Hibernate事务API586.3.事务模式(与反模式)636.3.1.Session-per-operation(每操作一个会话)反模式636.3.2.Session-per-request(

5、每请求一个会话)模式636.3.3.Conversations(对话)646.3.4.Session-per-application (每应用一个会话)666.4. 常见问题66第7章 JNDI66第章锁678.1.乐观锁688.1.1.指定版本号688.1.2.Timestamp(时间戳)718.2.悲观锁738.2.1.LockMode类73第9章Fetching(抓取)749.1.基础759.2.应用抓取策略769.2.1.不抓取789.2.2.通过查询动态抓取809.2.3.通过配置文件动态抓取81第10章 批处理8210.1.JDBC批处理82第11章 缓冲8311.1.配置二级缓存

6、8311.1.1.RegionFactory(注册工厂)8311.1.2.缓冲行为8411.2.管理缓冲数据86第十二章 12.拦截器和事件8612.1.拦截器 (Interceptors)8612.2.Native(原生、本地)事件系统8712.2.1.Hibernate声明式安全8812.3. JPA 回调91第13章 HQL与JPQL9413.1.大小写敏感性9713.2. 语句(Stataement)类型9713.2.1.Select语句9713.2.2.Update语句9813.2.3.Delete语句10013.2.4.Insert语句10013.3.FROM子句10213.3.1

7、.标识变量10213.3.2.Root(根)实体引用10213.3.3.显式join10313.3.4.隐式join(path 表达式)10613.3.5.集合成员引用10813.3.6.Polymorphism(多态)11113.4.表达式11213.4.1.标识变量11213.4.2.路径表达式11213.4.3.文本说明11213.4.4.参数11413.4.5.算术运算11713.4.6.Concatenation(串联)(运算)11713.4.7.聚合函数11813.4.8.Scalar(标量)函数11913.4.9.集合相关的表达式12113.4.10.实体类型12413.4.11

8、.CASE表达式12513.5. SELECT 子句12813.6. Predicates(谓词)12913.6.1.关系比较12913.6.2.空值谓词13213.6.3.Like谓词13213.6.4.Between谓词13313.6.5.In谓词13413.6.6.Exists 谓词13613.6.7.空集合谓词13713.6.8.集合成员谓词13713.6.9.NOT谓词13813.6.10.AND谓词13813.6.11.OR谓词13813.7. WHERE子句13813.8.分组13813.9.排序14013.10.查询API14113.10.1.Hibernate查询API141

9、13.10.2.JPA查询API145第14章Criteria14814.1.类型化criteria查询15014.1.1. 选择一个实体15014.1.2.选择一个表达式15114.1.3.选择多个值15214.1.4.选择wrapper(封装)15414.2.Tuple criteria 查询15614.3.FROM 子句15714.3.1.Roots(根)15714.3.2.Joins15914.3.3.抓取16014.4.路径表达式16114.5.使用参数161第15章NativeSQL查询(原生SQL查询,本地SQL查询)16215.1.使用SQLQuery16315.1.1.Sca

10、lar(标量)查询16315.1.2.实体查询16415.1.3.处理association(关联)与集合16415.1.4.返回多个实体16515.1.5.返回非托管实体16915.1.6.处理继承16915.1.7.参数16915.2.命名SQL查询16915.2.1.使用return-property显式指定列与别名18115.2.2.使用存储过程查询18215.3.自定义新建、更新、删除 的SQL语句18415.4.自定义SQL加载188Chapter16.Multi-tenancy(多租户)18916.1.什么是Multi-tenancy(多租户)19016.2.多租户数据处理方法1

11、9016.2.1.Separate databa(独立数据库)19016.2.2.独立的schema19116.2.3.数据分区(鉴别器)19216.3.Hibernate中的 Multi-tenancy(多租户)19316.3.1.MultiTenantConnectionProvider19416.3.2.CurrentTenantIdentifierResolver19516.3.3.缓冲19516.3.4.杂项19616.4. MultiTenantConnectionProvider实现策略196第17章 OSGi20017.1.OSGi规范与环境20117.2.hibernate-

12、osgi20117.3.features.xml20117.4.快速入门与演示20217.5.容器管理的JPA20217.5.1.企业级OSGi的JPA容器20217.5.2.persistence.xml20317.5.3.DataSource(数据源)20317.5.4.Bundle包的导入20417.5.5.获取EntityManger(实体管理器)20517.6.非托管JPA20617.6.1.persistence.xml20617.6.2.Bundle包的导入20617.6.3.获取EntityMangerFactory20617.7.非托管Native20817.7.1.Bund

13、le包的导入20817.7.2.获取SessionFactory20817.8.可选模块20917.9.扩展点20917.10.附加说明211第18章Envers21218.1.基础知识21318.2.配置21418.3.额外的映射注释21818.4.选择audit策略21818.5.版本日志219版本日志的数据21918.5.1.在版本控制中跟踪修改的实体名22218.6.在属性级别上跟踪实体变化22618.7.查询22618.7.1. 指定一个版本查询类的实体22718.7.2.按实体类的变化,查询版本22818.7.3.通过指定属性的变化查询实体的版本22918.7.4.按版本查询实体的

14、修改23018.8.条件audit23118.9.理解Envers Schema23118.10.使用Ant生成schema23318.11.映射异常23518.11.1.现在不会将来也不会支持的23518.11.2.现在不会将来会支持的23518.11.3.OneToMany+JoinColumn23518.12.高级:Audit表分区23618.12.1.audit表分区的好处23618.12.2.选择合适的列为audit表分区23618.12.3.Audit表分区示例23718.13.Envers有关的链接239第19章.数据库可移植性思考24019.1.可移植性基础24019.2.Di

15、alect(方言)24019.3.Dialect(方言)解析24019.4.标识符生成24119.5.数据库函数24219.6.类型映射243附录A Legacy Bootstrapping(过时的引导方式)243A.1.迁移245附录B Legacy(过时的)Hibernate Criteria查询247B.1.建立 Criteria实例248B.2.减小结果集248B.3.排序结果集249B.4.关联250B.5.动态关联抓取251B.6. Components(组件)252B.7.集合252B.8.Example查询252B.9. Projections(投影), 聚合与分组253B.1

16、0. Detached queries(分离式查询)与子查询255B.11.通过natural(自然)ID查询257参考258序言 面向对象的开发在处理关系型 数据库中的数据时是非常麻烦与消耗资源的。开发成本非常高的原因在于:关系型数据库中的数据与程序对象之间不匹配(译者注:数据库中的表如何变成程序的对象)。Hibernate是JAVA开发环境下对象-关系映射(Object/Relational Mapping及ORM)的解决方案。ORM是指一种映射技巧,ORM适用于对象模型与关系模型之间的匹配。参考Wikipedia(维基)的高级讨论组与Martin Fowler的文章OrmHate,其中都

17、提到了不匹配带来的问题。 虽然您可能认为已经有了强大的SQL,hibernate不是必需的,但是在做出判断前请了解一下hibernate。同时,一些基本概念的理解也有助于你对hibernate更快更全面的了解。这些基本概念中,数据建模原则是非常重要的。下面两个文章有助于您了解数据建模原则。、 了解一些基本的事务处理、设计模式比如:Unit of Work(工作单元)PoEAA或者“ApplicationTransaction(应用程序事务)”是非常有益的。这些我们将在本文档中讨论研究,但是预先了解一些会带来很大的帮助。 Hibernate不只关心java类到数据库表的映射(java类型到sql

18、类型的匹配),还提供了数据查询与检索工具。应用hibernate可以替换你手工处理SQL与JDBC的代码,它可以显著的减少开发时间。Hibernate的设计目标是减少工程中的SQL与JDBC操作。当然还有其它的数据持久化解决方案。但是Hibernate与其它方案不同在于它不阻断您使用强大的SQL与JDBC,它只是希望您将更多的精力用于关系设计与业务逻辑上。 Hibernate可能不是最好的data-centric applications(以数据为中心应用程序)的解决方案,它只是用存储过程来实现数据库业务逻辑。但是它是一个java中间层,用于提供面向对象的建模与业务逻辑。Hibernate可以

19、帮助您去除与封装数据库提供商特定的Sql代码,帮助您完成将数据结果集从表格形式转换成对象的形式。 参考以下内容,得到相关信息: 提示如果你是刚刚开始使用Hibernate,您可以从开始“Hibernate Getting Started Guide(Hibernate入门指南)”开始文档页,它包含快速教程以及很多介绍。还有一系列的专题讨论,适应不同层次的读者。 第章.Architecture(体系架构)目录1.1. 概述1.2.Contextual sessions (session上下文)1.1.概述Hibernate作为一个ORM解决方案,实际上位于java应用与关系数据库之间。可以参考上

20、图所示。JAVA应用使用HibernateAPI加载、存储、查询等操作,处理数据库中的数据。这里先简单介绍一下基本的HibernateAPI,稍后我们再讨论它的细节。 SessionFactory(会话工厂)(org.hibernate.SessionFactory)它是一个线程安全的,immutable(终态的),它是一个代理,表示应用程序域模型到数据库的映射,作为建立org.hibernate.Session(会话实例)的工厂。 SessionFactory的建立代价很大(译者注:内存、cpu占用很大),所以一个应用只能有一个SessionFactory。SessionFactory维护H

21、ibernate的所有Session(会话),二级缓冲,连接池,事务等等。 Session(会话)(org.hibernate.Session)Session(会话)是一个单线程,短生命周期的对象,是按Unit of Work(工作单元)PoEAA模式的概念构建的。 封装了JBDC的连接对象java.sql.Connection。作为一个org.hibernate.Transaction(事务)实例的工厂,维护应用程序domain model(数据模型、域模型)中通用(repeatable read可重复读取)的持久化内容(一级缓冲)。 Transaction(事务)(org.hibernat

22、e.Transaction)它是单线程,短生命周期的对象,它用于界定具体物理事务的范围。它作为一个抽象API接口用于隔离各种应用与底层的事务系统(JDBC, JTA, CORBA)。 1.2.Contextual sessions(session上下文)大多数应用程序使用Hibernate时需要某种形式的session“上下文”,一个特定的session(会话)影响整体特定的上下文范围。然而,跨应用程序的组建上下文是很难的;目前的观点是:不同的上下文定义了不同的范围。在Hibernate3以前,应用程序使用session有两种方式:一种是利用ThreadLocal(本地线程)加上辅助类如:Hi

23、bernateUtil,建立session(会话);另一种是使用第三方框架,如:Spring、Pico,它们提供基于上下文的,session(会话)的代理/拦截。 从Hibernate3.0.1版开始,加Sessionfactory.getcurrentsession()方法。最初此方法使用JTA的事务处理。在JTA自己的范围中与当前会话中一起使用。由此可以使用很成熟的JTA TransactionManager(JTA事务管理)实现。但是这要求所有应用程序都用 JTA事务管理,不管这个应用程序是否部署在J2EE容器中,你的session一定要使用基于JTA的上下文。 然而,从Hibernat

24、e3.1以后,SessionFactory.getCurrentSession()可以变成插件式的,为此一个新的扩展接口org.hibernate.context.spi.CurrentSessionContext与一个新的配置参数hibernate.current_session_context_class产生了,通过这一变化,允许定义可插拔的上下文范围与当前会话。 参考JAVA文档中org.hibernate.context.spi.CurrentSessionContext接口,其中详细讨论了这一约定。接口定义了唯一方法currentSession(),这个方法的实现类可以跟踪当前会话的

25、上下文。在外部Hibernate允许用三种方法来实现这一接口: org.hibernate.context.internal.JTASessionContext:由JTA事务界定当前会话范围与跟踪当前会话。这种处理方式与原来版本是完全一样。详情见javadocs。 org.hibernate.context.internal.ThreadLocalSessionContext:由执行的线程跟踪当前会话。详情见javadocs。 org.hibernate.context.internal.ManagedSessionContext:由执行的线程跟踪当前会话。然而你自己负责绑定与解绑Sessio

26、n(会话)实例,这些通常在类的静态方法中,这时Session(会话)不能打开,关闭,刷新,详情见javadocs。 通常,这个参数的值将被命名为使用的实现类。当通过外部插件来实现,这些要分别要对应三个短语:jta,thread,managed。 前两种实现都提供了“one session - one database transaction(一会话,一事务)”开发模式。这也可以称为“session-per-request(每请求一会话)”模式。开始结束一个Hibernate会话都是在数据库事务过程中定义的。如果计划使用经典的JSE平台的事务处理流程,而不使用JTA事务,建议在你的代码中用hib

27、ernateTransaction(事务)API来代替系统底层的事务过程。如果你使用JTA,你可以利用JTA接口来定义事务。如果你运行在支持CMT的EJB容器中,事务以声明的方式定义,你的代码中将不用处理事务与会话的操作。参考第6章,事务与并发控制有更多的信息与代码示例。 hibernate.current_session_context_class配置参数为org.hibernate.context.spi.CurrentSessionContext。为了向后兼容,如果没有设定此参数,但是org.hibernate.engine.transaction.jta.platform.spi.Jt

28、aPlatform被设定,hibernate将使用org.hibernate.context.internal.JTASessionContext。 第2章.Domain Model(域模型)目录2.1. POJO模型(POJO Domain Models)2.1.1. 实现无参构造2.1.2. 提供标识(identifier)属性2.1.3. 使用非final类2.1.4. 为持久化属性声明get,set方法 2.1.5. 实现equals()与hashCode()2.2. Dynamic(动态)模型术语domain model(域模型)来自于data modeling(数据建模)范畴。这个

29、模型最终描述的是你要解决的problem domain(问题域)。有时你听说过术语持久化类(persistent classes)。 归根结底,应用程序的domain model(域模型)是实体关系模型(ORM)中的核心角色。他拼装你想要map(映射)的类。Hibernate可以非常好的工作于POJO(Plain Old Java Object)或者JavaBean开发模式中。然而,这些规范都不是强制要求。事实上,Hibernate没在限制持久层对象的特质。你可以用其它方式表示domain model(域模型)(比如用java.util.Map的树状实例)。 注意尽管Hibernate没有将这

30、些规范看作是强制要求,但是JPA是要求的。因此如果你的应用有向JPA移植的可能性,你最好遵守严格的POJO模型。我们将指出在哪里涉及到这些问题。 本章将阐述domain model(域模型)的特征,然而,不讨论domain model(域模型)的全部内容。这是一个巨大的主题,它有自己的专用手册。参考Hibernate Domain Model Mapping Guide(域模型映射手册),hibernate文档页. 2.1.POJO 模型本节探讨定义为POJO的域模型 2.1.1.实现无参构造函数POJO要求实现一个无参构造函数,Hibernate与JPA都要求这样。 JPA要求这个构造函数声

31、明为public或者protected。Hibernate大多数情况下只关心可见性,只要系统的安全机制允许重写可见性就可以。这意思是说,如果你想支持运行时代理生成类,这个构造函数应该声明最小包可见(译者注:默认作用域)。 2.1.2.提供identifier(标识)属性 注意以前这被认为是可选的。然而在实体上不定义主键将被认为是过时的。在未来的版本中,将强制要求定义标识属性。 标识属性不一指要求是物理映射定义的主键列。然而,它一定映射到可以唯一标识一行的列上(译者注:唯一标识列)。 我们建议你在持久化类中声明一个统一命名的标识属性,你可以使用nullable(可空的)类型(即:非JAVA基本数

32、据类型)。 2.1.3.使用非final类 Hibernate 核心功能是通过运行时代理可以懒加载(lazy load)实体数据。这个功能依赖于实体类是非终态类(final)或者 实现一个声明过所有属性get 与set方法的接口。你可以坚持用终态类(final)并且不实现接口。但是你将不能使用代理进行懒加载关联抓取,并且这将限制你系统的优化选项。 注意从Hibernate5.0开始,我们提供了一个强大的全新的字节码处理器,用于处理懒加载。以前版本的hibernate中只有一个简单的字节码重写功能。 你也应该避免持久化属性的get,set方法为终态的(fianl)的,原因上面已经说过了。 2.1

33、.4.为持久化属性声明 get,set方法 虽然不是必须的,我们建议你遵守JavaBean规范来声明实体持久化属性的get,set方法。虽然Hibernate是可以直接访问实体的成员变量(field)。 这此属性(成员变量,set,get方法)不一定声明为public。Hibernate可以处理各种可见性(public, protected, package(译者注:默认属性),private)的属性。 2.1.5.实现 equals()与hashCode()方法 注意本节大部分内容讨论处理Hibernate会话(session)与实体的关系;如果你不熟悉实体的三种状态:manged(托管态)

34、(译者注:原来叫Persistent持久态,这次改名了,还是有什么变化?),transient(瞬时态、临时态),detached(脱管态、分离态),请参考这里 在域模型中是否实现equals()与hashCode()方法,如何实现他们。这一切在ORM中都是一个复杂的问题。 一般作为类中的标识类型,在其id值上必须实现 equals/hashCode方法。有两种情况不一定要实现equals/hashCode方法,一是:当用户类使用联合主键时;二是:下面讨论的一些特殊情况。用户定义的类使用了复合键使用这种类用作定义用户类型的复合主键。除了以上这种情况以及下面讨论的很少一些情况下,你不必一定实现e

35、quals/hashCode方法。 那么,有什么烦恼?通常情况下,大多数的Java对象在其的标识属性上提供一个内置的equals()和hashCode()方法,因此,每个新的对象与其他对象不同。这通常是我们在普通的Java编程所要做的。然而,事实上当我们从数据库中取得数据时,很可能出现多个实例有相同的值。这时你应该开始考虑重定义内置的equals()和hashCode()方法。每次从数据库中加载一个特定下面代码的Person类,我们自然将得到唯一的实例。Hibernate努力确保在一个会话中不发生这样的情况(译者注,多次加载同一行数据,对象应该是一个)。事实上,Hibernate在一个特定内部

36、会话中保证数据行的ID与JAVA的ID对等的关系。因此如果你在一个会话中请求一个特定对象多次,事实上你将得到同一个实例: 示例2.1.标识符(ID)的作用域Session session = .;Person p1 = session.get( Person.class, 1 );Person p2 = session.get( Person.class, 1);/assert p1 = p2; 的结果为true思考另一个例子中使用一个持久化的java.util.Set: 示例2.2.Set在会话作用域中的用法Session session = .;Club club = session.ge

37、t( Club.class, 1 );Person p1 = session.get( Person.class, 1 );Person p2 = session.get( Person.class, 1);club.getMembers().add( p1 );club.getMembers().add( p2 );/ 以下计算结果为true,也就是只加入了一个对象 assert club.getMembers.size() = 1;当从不同的会话加载时: 示例2.3.混合会话Session session1 = .;Session session2 = .;Person p1 = sess

38、ion1.get( Person.class, 1 );Person p2 = session2.get( Person.class, 1);/计算结果为false assert p1 = p2;Session session1 = .;Session session2 = .;Club club = session1.get( Club.class, 1 );Person p1 = session1.get( Person.class, 1 );Person p2 = session2.get( Person.class, 1);club.getMembers().add( p1 );clu

39、b.getMembers().add( p2 );/计算结果取决于:assert club.getMembers.size() = 1;最后一个示例的具体计算结果取决于Person类是否实现equals/hashCode方法,如果是实现了,结果怎么样。 考虑另一种情况: 示例2.4.瞬时态实体的赋值Session session = .;Club club = session.get( Club.class, 1 );Person p1 = new Person(.);Person p2 = new Person(.);club.getMembers().add( p1 );club.getM

40、embers().add( p2 );/这个计算结果.再次取决assert club.getMembers.size() = 1;在某些情况下,你是否在会话外处理实例(不管是瞬态与分离态),特别是你将在java集合中使用对象时,你们应该考虑实现equals/hashCode方法。 常用的初始化equals/hashCode方法是,使用实体的ID属性作为计算的基础: 示例2.5.本地实现equals/hashCode方法 Entitypublic class Person IdGeneratedValueprivate Integer id;.Overridepublic int hashCod

41、e() return id != null ? id.hashCode() : 0;Overridepublic boolean equals() if ( this = o ) return true;if ( !( o instanceof Person ) ) return false;if ( id = null ) return false;final Person other = (Person) o;return id.equals( other.id );事实证明,正如我们在上面的示例看到的那样,当向一个SET添加一个Person类的瞬态实例时,结果取决于是否实现现equals

42、/hashCode方法。 示例2.6.还是麻烦Session session = .;session.getTransaction().begin();Club club = session.get( Club.class, 1 );Person p1 = new Person(.);Person p2 = new Person(.);club.getMembers().add( p1 );club.getMembers().add( p2 );session.getTransaction().commit();/ 下面代码结果为false!assert club.getMembers().c

43、ontains( p1 );这里的问题是以下内容有冲突:1、使用生成器生成的标识符(id);2、SET集合的约定;3、equals/hashCode方法的实现。也就是说,对象的equals/hashCode值作为SET集合的一部分不应该被改变,但是这里究竟发生了什么?因为equals/hashCode是以生成ID(标识符)为基础计算的,直到session.getTransaction().commit() 调用,都没有被赋值. 注意,这里涉及到的是生成的标识符(ID)。如果你使用已赋值的标识符就没有这个问题,假设标识符在加入到集合之前已经被赋值。 另一个选择是强制标识符被生成,并且在加入集合之

44、前: 示例2.7.强制生成标识符(ID)Session session = .;session.getTransaction().begin();Club club = session.get( Club.class, 1 );Person p1 = new Person(.);Person p2 = new Person(.);session.save( p1 );session.save( p2 );session.flush();club.getMembers().add( p1 );club.getMembers().add( p2 );session.getTransaction()

45、.commit();/ 将得到false!assert club.getMembers().contains( p1 );但是这常常是不可行的。 最后,更好的方法是实现equals/hashCode方法,利用natural-id(自然ID)或者business-key(业务主键)。 示例2.8.更好的equals/hashCode使用natural-id(自然ID)Entitypublic class Person IdGeneratedValueprivate Integer id;NaturalIdprivate String ssn;protected Person() / ctor f

46、or ORMpublic Person(String ssn) / ctor for appthis.ssn = ssn;.Overridepublic int hashCode() assert ssn != null;return ssn.hashCode();Overridepublic boolean equals() if ( this = o ) return true;if ( !( o instanceof Person ) ) return false;final Person other = (Person) o;assert ssn != null;assert othe

47、r.ssn != null;return ssn.equals( other.ssn );正如你看到的equals/hashCode的问题不是小事,也没有一种万能的解决方案。 2.2.Dynamic(动态)模型持久化实体不一定用POJO/JavaBean这一种方式表示。Hibernate也支持动态模型(用Map或者运行时Map)。用这种方法,你不用改写持久化类,只是用映射文件。 注意动态模型的映射已经超出了本文档的范围。我们只讨论在Hibernate中使用这些模型,但是有关映射的详情请参考Hibernate Domain Model Mapping。 一个指定的实体在一个指定的SessionF

48、actory中只能有一种实体模型。但是这些在以前的版本中就已经更改了,现在允许为一个实体定义多个实体模型并且允许使用者选择如何加载。实体模型现在可以与域模型混合;动态实体可参考一个POJO实体,反之亦然。 示例2.9.使用动态域模型工Session s = openSession();Transaction tx = s.beginTransaction();/ 建立一个custormer实体Map david = new HashMap();david.put(name, David);/ 建立一个 organization实体Map foobar = new HashMap();fooba

49、r.put(name, Foobar Inc.);/ 连接两者david.put(organization, foobar);/ 保存两者s.save(Customer, david);s.save(Organization, foobar);mit();s.close();动态模型主要的优点在于:快速的变化与运行,因为原型不用实体类实现。主要的缺点在于:你不能进行编译时检查,并且可能要处理大量的运行时异常。然而,做为Hibernate映射的结果,数据库schema可以更容易的标准化与合理化,并且以后在动态模型上添加更合适的域模型。 动态模型大量用于处理某些整合用例,例如:利用动态模型描述历史

50、数据被广泛使用。 第3章Bootstrap(引导、启动目录3.1. Native(原生、本地)引导3.1.1. 构建ServiceRegistry3.1.2. 构建 Metadata3.1.3. 构建SessionFactory3.2. JPA引导3.2.1. JPA兼容模式的引导3.2.2. Proprietary 2-phase引导术语bootstrapping(引导)是指初始化并且启动软件的组件。在Hibernate中我们将具体讨论建立全功能SessionFactory实例的过程或者在JPA中建立EntityManagerFactory实例的过程。这些过程各不相同。 注意本章不是关注于所

51、有引导的可能性。这些将包括在稍后的相关章节中。取而代之,我们关注于执行引导的API调用。 3.1. Native (原生、本地)引导本节讨论 Hibernate SessionFactory的引导过程。具体讨论5.0中重新设计的引导API。对于Legacy(旧版、过时)引导API的讨论,请参考 附录A Legacy(旧版、过时)引导 3.1.1.构建ServiceRegistry Native(原生、本地)引导的第一步是建立ServiceRegistry,ServiceRegistry持有Hibernate引导与运行时所需要服务。 事实上,我们涉及到建立2种不同的ServiceRegistri

52、es。第一种是org.hibernate.boot.registry.BootstrapServiceRegistry。BootstrapServiceRegistry持有Hibernate引导与运行时所需要服务。这归结为3个服务: org.hibernate.boot.registry.classloading.spi.ClassLoaderService -它控制Hibernate如何与类加载器的互动org.hibernate.integrator.spi.IntegratorService-它控制管理与发现org.hibernate.integrator.spi.Integrator的实

53、例。 org.hibernate.boot.registry.selector.spi.StrategySelector-它控制Hibernate如何处理各种约定策略的实现。这是一个功能强大的服务,但对它的全面讨论超出本手册的范围。 如果你没有特殊要求,可以使用Hibernate默认行为处理有关BootstrapServiceRegistry服务(这是经常发生的情况,特别是在java SE环境中),这样就可以跳过建立BootstrapServiceRegistry的过程。 如果你希望改变BootstrapServiceRegistry的构建,可以通过控制org.hibernate.boot.r

54、egistry.BootstrapServiceRegistryBuilder类来实现: 示例3.1. 控制BootstrapServiceRegistry构建过程BootstrapServiceRegistryBuilder bootstrapRegistryBuilder= new BootstrapServiceRegistryBuilder();/ 添加一个自定义的类加载器 bootstrapRegistryBuilder.applyClassLoader( mySpecialClassLoader );/或手工添加一个集成器(Integrator) bootstrapRegistry

55、Builder.applyIntegrator( mySpecialIntegrator );.BootstrapServiceRegistry bootstrapRegistry = bootstrapRegistryBuilder.build();该BootstrapServiceRegistry的服务不能被继承(添加),也不能被重写(替换)。 第二种ServiceRegistry是org.hibernate.boot.registry.StandardServiceRegistry.你将需要配置StandardServiceRegistry,这是通过org.hibernate.boot.

56、registry.StandardServiceRegistryBuilder来实现: 示例3.2.构建BootstrapServiceRegistry / 这是一个隐式建立BootstrapServiceRegistry的例子 StandardServiceRegistryBuilder standardRegistryBuilder= new StandardServiceRegistryBuilder();/ 这是一个显式建立BootstrapServiceRegistry的例子BootstrapServiceRegistry bootstrapRegistry = .;Standard

57、ServiceRegistryBuilder standardRegistryBuilder= new StandardServiceRegistryBuilder( bootstrapRegistry );一个StandardServiceRegistry是高度可配置的,这通过StandardServiceRegistryBuilder完成。参考关于StandardServiceRegistryBuilder的javadocs了解所有细节。一些相关的具体方法有: 示例3.3.控制StandardServiceRegistry的构建过程StandardServiceRegistryBuilde

58、r standardRegistryBuilder = .;/ 通过资源查找加载某些属性(译者注:属性文件方式加载 ) standardRegistryBuilder.loadProperties( org/hibernate/example/MyProperties.properties );/ 从cfg.xml配置文件来配置注册信息 standardRegistryBuilder.configure( org/hibernate/example/my.cfg.xml );/ 应用随机设置 standardRegistryBuilder.applySetting( myProp, some

59、value );/ 应用服务初始化器 standardRegistryBuilder.addInitiator( new CustomServiceInitiator() );/ 应用服务接口 standardRegistryBuilder.addService( SomeCustomService.class, new SomeCustomServiceImpl() );/ 最后建立StandardServiceRegistry StandardServiceRegistry standardRegistry = standardRegistryBuilder.build();3.1.2.构建Metadata Native(原生、本地)引导的第二步是建立org.hibernate.boot.Metadata对象,这个对象包括程序域模型的解析结果并且这些结果映射到数据库中。显然第一步是需要找到这些被解析

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!