- 浏览: 65501 次
- 性别:
- 来自: 深圳
-
文章分类
最新评论
-
hzfeibao:
Thank you
discriminator-value -
nforce_com:
...
discriminator-value -
zjcheng:
xuexi
discriminator-value -
wenjinglian:
学习
discriminator-value -
huoligg:
aspectj是一个强大的AOP工具,上面的类型模型是aspe ...
类型模型
对象和关系数据库之间的映射是用一个XML文档(XML document)来定义的。这个映射文档被设计为易读的,并且可以手工修改。映射语言是以.NET为中心的,意味着映射是按照持久化类的定义来创建的,而非表的定义。
请注意,虽然很多Hibernate用户选择手工定义XML映射文档,也有一些工具来生成映射文档,包括XDoclet,Middlegen和AndroMDA.
译者注:这里是NHibernate文档中一处没有从Hibernate文档中转换过来的部分,NHibernate中并没有像XDoclet,Middlegen和AndroMDA这样的工具,我一般会采用MyGeneration这样的代码生成工具来生成XML配置文档。
让我们从一个映射的例子开始:
<?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.0" namespace="Eg" assembly="Eg"> <class name="Cat" table="CATS" discriminator-value="C"> <id name="Id" column="uid" type="Int64"> <generator class="hilo"/> </id> <discriminator column="subclass" type="Char"/> <property name="Birthdate" type="Date"/> <property name="Color" not-null="true"/> <property name="Sex" not-null="true" update="false"/> <property name="Weight"/> <many-to-one name="Mate" column="mate_id"/> <set name="Kittens"> <key column="mother_id"/> <one-to-many class="Cat"/> </set> <subclass name="DomesticCat" discriminator-value="D"> <property name="Name" type="String"/> </subclass> </class> <class name="Dog"> <!-- mapping for Dog could go here --> </class> </hibernate-mapping>
我们现在开始讨论映射文档的内容。我们只描述NHibernate在运行时用到的文档元素和属性。映射文档还包括一些额外的可选属性和元素,它们在使用schema导出工具的时候会影响导出的数据库schema结果。(比如, not-null
属性。)
所有的XML映射都需要使用nhibernate-mapping-2.0 schema。目前的schema可以在NHibernate的资源路径或者是NHibernate.dll
的嵌入资源(Embedded Resource)中找到。NHibernate总是会优先使用嵌入在资源中的schema文件。
在使用VisualStudio.NET时,你应该将hibernate-mapping
拷贝到C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml
路径中,以获得智能感知功能。
这个元素包括四个可选的属性。schema
属性,指明了这个映射所引用的表所在的schema名称。假若指定了这个属性,表名会加上所指定的schema的名字扩展为全限定名。假若没有指定,表名就不会使用全限定名。default-cascade
指定了未明确注明cascade属性的属性和集合类会采取什么样的默认级联风格。auto-import属性默认让我们在查询语言中可以使用非全限定名的类名。default-access
告诉我们怎么访问属性值。
<hibernate-mapping schema="schemaName" (1) default-cascade="none|save-update" (2) auto-import="true|false" (3) default-access="property|field|nosetter|ClassName" (4) assembly="assembly.name" (5) namespace="namespace.name" (6) >
(1) |
|
(2) |
|
(3) |
|
(4) |
|
(5) |
|
(6) |
|
假若你有两个持久化类,它们的非全限定名是一样的(就是在不同的命名空间里面--译者注),你应该设置auto-import="false"
。假若说你把一个“import过”的名字同时对应两个类, NHibernate会抛出一个异常。
你可以使用class
元素来定义一个持久化类:
<class name="ClassName" (1) table="tableName"(2) discriminator-value="discriminator_value"(3) mutable="true|false"(4) schema="owner"(5) proxy="ProxyInterface"(6) dynamic-update="true|false"(7) dynamic-insert="true|false"(8) polymorphism="implicit|explicit"(9) where="arbitrary sql where condition"(10) persister="PersisterClass"(11) lazy="true|false"(12) />
(1) |
|
(2) |
|
(3) |
|
(4) |
|
(5) |
|
(6) |
|
(7) |
|
(8) |
|
(9) |
|
(10) |
|
(11) |
|
(12) |
|
若指明的持久化类实际上是一个接口,也可以被完美地接受。其后你可以用 <subclass>
来指定该接口的实际实现类名。你可以持久化任何static(静态的)内部类。记得应该使用标准的类名格式,就是说比如:Eg.Foo+Bar
不可变类,mutable="false"
不可以被应用程序更新或者删除。这可以让NHibernate做一些小小的性能优化。
可选的proxy属性可以允许延迟加载类的持久化实例。NHibernate开始会返回实现了这个命名接口或者子类(通过的Castle.DynamicProxy)。当代理的某个方法被实际调用的时候,真实的持久化对象才会被装载。参见下面的“用于延迟装载的代理”。
Implicit (隐式)的多态是指,如果查询中给出的是任何超类、该类实现的接口或者该类的名字,都会返回这个类的实例;如果查询中给出的是子类的名字,则会返回子类的实例。Explicit (显式)的多态是指,只有在查询中给出的明确是该类的名字时才会返回这个类的实例;同时只有当在这个 <class>
的定义中作为 <subclass>
或者 <joined-subclass>
出现的子类,才会可能返回。 大多数情况下,默认的polymorphism="implicit"
都是合适的。 显式的多态在有两个不同的类映射到同一个表的时候很有用。(允许一个“轻型”的类,只包含部分表字段)。
persister属性可以让你定制这个类使用的持久化策略。你可以指定你自己实现的NHibernate.Persister.EntityPersister
的子类,你甚至可以完全从头开始编写一个NHibernate.Persister.IClassPersister
接口的实现,可能是用储存过程调用、序列化到文件或者LDAP数据库来实现的。参阅NHibernate.DomainModel.CustomPersister
,这是一个简单的例子(“持久化”到一个Hashtable)。
请注意dynamic-update
和dynamic-insert
的设置并不会继承到子类,所以在<subclass>
或者<joined-subclass>
元素中可能需要再次设置。这些设置是否能够提高效率要视情形而定。请用你的智慧决定是否使用。
被映射的类必须声明对应数据库表主键字段。大多数类有一个属性,为每一个实例包含唯一的标识。 <id>
元素定义了该属性到数据库表主键字段的映射。
<id name="propertyName" (1) type="typename" (2) column="column_name" (3) unsaved-value="any|none|null|id_value" (4) access="field|property|nosetter|ClassName"> (5) <generator class="generatorClass"/> </id>
(1) |
|
(2) |
|
(3) |
|
(4) |
|
(5) |
|
如果name
属性不存在,会认为这个类没有标识属性。
unsaved-value
属性很重要!如果你的类的标识属性不是默认为null
的,你应该指定正确的默认值。特别重要的是在使用值类型System.ValueType
例如System.Int32
或者 System.Guid
作为你的<id>
属性时确保清楚的设置这个属性,因为System.ValueType
对象不可能为null
值。
还有一个另外的<composite-id>
声明可以访问旧式的多主键数据。我们强烈不鼓励使用这种方式。
必须声明的 <generator>
子元素是一个.NET类的名字,用来为该持久化类的实例生成唯一的标识。如果这个生成器实例需要某些配置值或者初始化参数,用 <param>
元素来传递。
<id name="Id" type="Int64" column="uid" unsaved-value="0"> <generator class="NHibernate.Id.TableHiLoGenerator"> <param name="table">uid_table</param> <param name="column">next_hi_value_column</param> </generator> </id>
所有的生成器都实现NHibernate.Id.IdentifierGenerator
接口。这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,NHibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:
identity
对DB2,MySQL, MS SQL Server, Sybase和HypersonicSQL的内置标识字段提供支持。返回的标识符是 Int64
, Int32
或者 Int16
类型的。
sequence
(序列) 对DB2,MySQL, PostgreSQL, Oracle的内置标识字段提供支持。返回的标识符是Int64
Int32
或者 Int16
类型的。
hilo
(高低位) 使用一个高/低位算法来高效的生成Int64
, Int32
或者 Int16
类型的标识符。给定一个表和字段(默认分别是hibernate_unique_key
和next
)作为高位值得来源。高/低位算法生成的标识符只在一个特定的数据库中是唯一的。
seqhilo
(使用序列的高低位) 使用一个高/低位算法来高效的生成Int64
, Int32
或者 Int16
类型的标识符,给定一个数据库序列(sequence)的名字。
uuid.hex
用一个System.Guid
和它的ToString(string format)
方法生成字符串类型的标识符。字符串的长度取决于 format
的配置。
uuid.string
用一个新的System.Guid
产生一个byte[]
,把它转换成字符串。
guid
用一个新的System.Guid
作为标识符。
guid.comb
用Jimmy Nilsson在文章http://www.informit.com/articles/article.asp?p=25862中描述的算法产生一个新的System.Guid
。
native
(本地) 根据底层数据库的能力选择 identity
, sequence
或者 hilo
中的一个。
assigned
(程序设置) 让应用程序在save()
之前为对象分配一个标示符。
foreign
(外部引用) 使用另外一个相关联的对象的标识符。和<one-to-one>
联合一起使用。
hilo
和 seqhilo
生成器给出了两种hi/lo算法的实现,这是一种很令人满意的标识符生成算法。第一种实现需要一个“特殊”的数据库表来保存下一个可用的“hi”值。第二种实现使用一个Oracle风格的序列(在被支持的情况下)。
<id name="Id" type="Int64" column="cat_id"> <generator class="hilo"> <param name="table">hi_value</param> <param name="column">next_value</param> <param name="max_lo">100</param> </generator> </id>
<id name="Id" type="Int64" column="cat_id"> <generator class="seqhilo"> <param name="sequence">hi_value</param> <param name="max_lo">100</param> </generator> </id>
很不幸,你在为NHibernate自行提供Connection的时候无法使用hilo
。Hibernate必须能够在一个新的事务中得到一个"hi"值。
<id name="Id" type="String" column="cat_id"> <generator class="uuid.hex"> <param name="format">format_value</param> <param name="seperator">seperator_value</param> </generator> </id>
UUID是通过调用Guid.NewGuid().ToString(format)
产生的。format值的设置请参考MSDN文档。默认的seperator
很少也不应该被改变。format
决定是否配置好的seperator
能替换默认的seperator,并提供给自己使用(译者注:此句可能和原文有出入,请参见英文文档)。
guid
标识符通过调用Guid.NewGuid()
产生。 为了提升Guids在MS SQL中作为主键,外键和索引的一部分时的性能,可以使用guid.comb
。在别的数据库中使用guid.comb
的好处是支持非标准的GUID。
对于内部支持标识字段的数据库(DB2,MySQL,Sybase,MS SQL),你可以使用identity
关键字生成。对于内部支持序列的数据库(DB2,Oracle, PostgreSQL),你可以使用sequence
风格的关键字生成。这两种方式对于插入一个新的对象都需要两次SQL查询。当使用MS SQL并且采用identity
主键生成器,select SCOPE_IDENTITY()
将会被附加到insert
的sql语句,因而不可避免的执行两个不同的IDbCommand
。
<id name="Id" type="Int64" column="uid"> <generator class="sequence"> <param name="sequence">uid_sequence</param> </generator> </id>
<id name="Id" type="Int64" column="uid" unsaved-value="0"> <generator class="identity"/> </id>
对于跨平台开发,native
策略会从identity, sequence 和hilo中进行选择,取决于底层数据库的支持能力。
<composite-id name="propertyName"(1) class="ClassName"(2) unsaved-value="any|none"(3) access="field|property|nosetter|ClassName"> <key-property name="propertyName" type="typename" column="column_name"/> <key-many-to-one name="propertyName class="ClassName" column="column_name"/> ...... </composite-id>
如果表使用联合主键,你可以把类的多个属性组合成为标识符属性。<composite-id>
元素接受<key-property>
属性映射和<key-many-to-one>
属性映射作为子元素。
<composite-id> <key-property name="medicareNumber"/> <key-property name="dependent"/> </composite-id>
你的持久化类必须重载Equals()
和HashCode()
方法,来实现组合的标识符判断等价.也必须实现Serializable
接口
不幸的是,这种组合关键字的方法意味着一个持久化类是它自己的标识。除了对象自己之外,没有什么方便的“把手”可用。你必须自己初始化持久化类的实例,在使用组合关键字Load()
持久化状态之前,必须填充他的联合属性。我们会在TODO:LINKTOCOMPENENTS中说明一种更加方便的方法,把联合标识实现为一个独立的类,下面描述的属性只对这种备用方法有效:
在"一棵对象继承树对应一个表"的策略中,<discriminator>
元素是必需的,它声明了表的识别器字段。识别器字段包含标志值,用于告知持久化层应该为某个特定的行创建哪一个子类的实例。只能使用如下受到限制的一些类型:String
, Char
, Int32
, Byte
, Int16
, Boolean
, YesNo
, TrueFalse
.
<discriminator column="discriminator_column"(1) type="discriminator_type"(2) force="true|false"(3) insert="true|false" (4) />
(1) |
|
(2) |
|
(3) |
|
(4) |
|
标识器字段的实际值是根据<class>
和<subclass>
元素的discriminator-value
得来的.
force
属性仅仅是在表包含一些未指定应该映射到哪个持久化类的时候才是有用的。这种情况不是经常会遇到。
元素<version>
是可选的,表明表中包含附带版本信息的数据。这在你准备使用长事务(long transactions)的时候特别有用。(见后)
<version column="version_column"(1) name="propertyName"(2) type="typename"(3) access="field|property|nosetter|ClassName"(4) unsaved-value="null|negative|undefined|value"(5) />
(1) |
|
(2) |
|
(3) |
|
(4) |
|
(5) |
|
版本号必须是以下类型: Int64
, Int32
, Int16
, Ticks
, Timestamp
, 或者 TimeSpan
.
可选的<timestamp>
元素指明了表中包含时间戳数据。这用来作为版本的替代。时间戳本质上是一种对乐观锁定的一种不是特别安全的实现。当然,有时候应用程序可能在其他方面使用时间戳。
<timestamp column="timestamp_column"(1) name="propertyName"(2) access="field|property|nosetter|ClassName"(3) unsaved-value="null|negative|undefined|value"(4) />
(1) |
|
(2) |
|
(3) |
|
(4) |
|
注意, <timestamp>
和<version type="timestamp">
是等价的。
<property>
元素为类声明了一个持久化的属性。
<property name="propertyName"(1) column="column_name"(2) type="typename"(3) update="true|false"(4) insert="true|false"(5) formula="arbitrary SQL expression"(6) access="field|property|nosetter|ClassName"(7) />
(1) |
|
(2) |
|
(3) |
|
(4) |
|
(5) |
|
(6) |
|
(7) |
|
typename可以是如下几种:
-
NHibernate 基础类型之一 (比如:
Int32, String, Char, DateTime, Timstamp, Single, Byte[], Object, ...
). -
基础类型的.NET类型名 (比如:
System.Int16, System.Single, System.Char, System.String, System.DateTime, System.Byte[], ...
). -
枚举
System.Enum
名 (比如:Eg.Color
). -
一个可以序列化的 .NET 类的名字。
-
一个自定义类型的类的名字。(比如:
Illflow.Type.MyCustomType, Illflow
).
如果你没有指定类型,NHibernate会使用反射来得到这个名字的属性,以此来猜测正确的NHibernate类型。NHibernate会对属性读取器(getter访问器)的返回类进行解释,按照规则2,3,4的顺序。然而,这并不足够。 在某些情况下你仍然需要type
属性。(比如,为了区别NHibernate.DateTime
和NHibernate.Timestamp
,或者为了指定一个自定义类型。)
access
属性用来让你控制NHibernate如何在运行时访问属性。access
的值属性应该用 access-strategy.naming-strategy
的格式。.naming-stragey
通常不需要设置。
表4.1 访问策略(Access Strategy)
property |
默认值,NHibernate使用属性的get/set访问。这种访问策略(Access Strategy)不应该使用命名策略(Naming Strategy),因为 |
field |
NHibernate将会直接访问字段。NHibernate使用 |
nosetter |
NHibernate将会在设置值时直接访问字段,获得值时访问属性。当你的API使用者不能直接改变值,因而只为属性只提供了get访问器时,你可以用这个策略。NHibernate使用 |
ClassName |
如果NHibernate内置的访问策略(Access Strategie)不能满足你的要求。你可以通过实现 |
表4.2 命名策略(Naming Strategy)
camelcase |
|
camelcase-underscore |
|
lowercase |
|
lowercase-underscore |
|
pascalcase-underscore |
|
pascalcase-m-underscore |
|
发表评论
-
回顾总结2
2009-03-09 15:29 827五、一对多关系映射(回归一个班级只有多个学生) 1、 基于 ... -
回顾总结1
2009-03-09 15:18 797一、实体对象的生命周期 实体对象的生命周期在Hibernat ... -
Hibernate Cache
2008-12-25 17:02 1317Cache In Hibernate HIBERNATE中的C ... -
default-access="field ¦property ¦ClassName"
2008-12-25 11:54 1641default-access="field ¦pro ... -
native与assigned
2008-12-24 15:53 1545在用Hibernate的时候,当有表中的主键是库自动生成的时候 ... -
subclass的用法
2008-12-24 11:15 1738看到jBPM中大量使用了sub ... -
Hibernate之component、composite-id、collection映射
2008-12-24 11:07 3876Hibernate之component、composite-i ... -
discriminator-value
2008-12-24 10:57 9065可能经常遇到这样的情 ... -
关于unsaved-value
2008-12-11 17:01 878从夏昕的 hibernate 开发 ... -
O/R Mapping基础(续二)
2008-11-21 20:56 1385子类(subclass) 最后,多态持久化需要为 ... -
O/R Mapping基础(续一)
2008-11-21 20:50 1166多对一(many-to-one) 通过many- ...
相关推荐
2. O/R Mapping 概念:讲解什么是 O/R Mapping、为什么需要 O/R Mapping,以及 O/R Mapping 的优点和缺点。 3. 常见 O/R 框架:介绍几种常见的 O/R 框架,包括 Hibernate、Entity Framework、TopLink 等。 4. ...
Hibernate是Java领域中一款流行的持久化框架,它实现了对象关系映射(O/R Mapping),将复杂的数据库操作转化为对Java对象的操作,从而简化了开发过程。本文主要围绕Hibernate 3.2的学习笔记,涵盖其基本概念、配置...
1. **O/R Mapping基础** O/R Mapping是将对象模型与关系数据模型进行映射的技术,它允许程序员以面向对象的方式处理数据库。Hibernate通过XML或注解方式定义映射规则,实现了对象与数据库表之间的透明交互。 2. **...
Hibernate的底层实现是基于O/R Mapping(对象关系映射)的原理。O/R Mapping是将Java对象映射到关系型数据库表的中间层。它的目的是简化Java开发者对数据库的操作,让开发者以面向对象的方式进行数据库编程,而非...
2. **O/R Mapping**:对象关系映射,是ORM的核心概念。它通过定义规则将数据库表映射为类,表中的字段映射为类的属性,从而实现对象与数据库记录的对应。这样,开发者可以直接操作对象,而无需关心底层SQL语句的编写...
【HIBERNATE入门】是针对Java开发者的培训资料,主要介绍了如何入门并掌握Hibernate这一流行的O/R Mapping框架。Hibernate是一种用于简化Java应用程序与数据库交互的开源库,它通过对象关系映射(O/R Mapping)技术...
AutoJava根据O/R Mapping规则生成表对应的Java对象,并且生成了所有的添加、删除、修改、查询等底层数据库操作代码。借助于AutoJava我们基本上不用再写与数据库相关的操作代码,只需要在此基础上实现相关的业务逻辑...
【一、O/R Mapping】 O/R Mapping,即对象关系映射,是将对象模型与关系数据库之间进行映射的技术。在Hibernate中,O/R Mapping允许开发者以面向对象的方式来操作数据库,而无需关心底层的SQL语句。这极大地提高了...
总结,这份hibernate培训ppt提供了一个基础的Hibernate学习框架,帮助开发者理解O/R Mapping的核心概念,并学会如何利用Hibernate进行实际的数据库操作。虽然可能在深度上有所欠缺,但对于初学者而言,它是一个良好...
【Hibernate快速学习PPT】是针对Java开发人员的一份教程资料,主要讲解了对象关系映射(Object/Relationship Mapping,简称O/R Mapping)框架Hibernate的核心概念和应用。这份PPT由加拿大嘉木华公司(JetGuo)提供,...
Hibernate作为优秀的O/R Mapping框架,具有开源、成熟、广泛使用等优点,且被JBoss选为实现Entity Beans的基础。使用Hibernate开发时,主要包括三个步骤:设计持久化类、建立类与数据库的映射,以及开发应用程序。...
《SQL2JAVA:深入理解O/R Mapping工具》 在当今的软件开发中,尤其是在企业级应用领域,数据库管理和数据操作是至关重要的环节。SQL2JAVA作为一个O/R Mapping(对象关系映射)工具,旨在简化数据库与Java应用程序...
本教程旨在帮助学员深入理解O/R Mapping原理,专注于流行的Java持久化框架Hibernate。学习此教程前,建议学员具备Java、SQL、JDBC的基础知识,以及面向对象开发的经验。通过培训,学员应能了解Hibernate的架构,掌握...
1. **O/R Mapping**:Object-Relational Mapping,对象关系映射,是将数据库中的关系数据模型映射到面向对象的编程语言中的一种技术。通过O/R Mapping,开发者可以避免直接编写SQL语句,而是以对象的形式处理数据,...
综上所述,"汤阳光Hibernate3.6(基础).doc"文档详细讲解了Hibernate 3.6的基础知识,包括对象持久化的概念、分层架构的运用以及Hibernate在数据访问层中的实现方式,是学习Hibernate和O/R Mapping的宝贵资源。...
ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 (O/R Mapping) 解决方案,早期被称为 ObjectSpace,现已经包含在 Visual Studio 2008 Service Pack 1 以及 .NET Framework 3.5 Service ...
Hibernate是一种强大的Object-Relational Mapping(O/R Mapping)工具,它允许开发者将Java对象与关系数据库中的表进行映射,从而简化数据库操作。 **一、持久化层—O/R Mapping** 在基于B/S的三层架构中,业务...
Hibernate 是一个流行的开源 Object-Relational Mapping (O/R Mapping)框架,它在Java Web开发中广泛应用于数据访问层,极大地简化了数据库操作。O/R Mapping 是一种技术,旨在消除对象世界和关系数据库之间的差异,...
本培训材料主要针对Hibernate这一流行的Java对象关系映射(ORM)框架,旨在帮助已经熟悉Java、SQL和JDBC的开发者深入理解O/R Mapping原理,掌握Hibernate的使用,以便在实际项目开发中有效地利用Hibernate进行持久化...