最后,多态持久化需要为父类的每个子类都进行声明。对于我们建议的“每一棵类继承树对应一个表”的策略来说,就需要使用<subclass>
声明。
<subclass
name="ClassName"(1)
discriminator-value="discriminator_value"(2)
proxy="ProxyInterface"(3)
dynamic-update="true|false"
dynamic-insert="true|false"
extends="BaseMappedClassName"> (4)
<property ... / >
...
<subclass/>
另外一种情况,如果子类是持久化到一个属于它自己的表(每一个子类对应一个表的映射策略),那么就需要使用<joined-subclass>
元素。
<joined-subclass
name="ClassName"(1)
table="tableName" (2)
proxy="ProxyInterface"(3)
dynamic-update="true|false"
dynamic-insert="true|false"
extends="BaseMappedClassName"> (4)
<key ... >
<property ... / >
...
<joined-subclass/>
这种映射策略不需要指定辨别标志(discriminator)字段。但是,每一个都必须使用 <key>
元素指定一个表字段包含对象的标识符。
假设你的应用程序有两个同样名字的持久化类,但是你不想在NHibernate查询中使用他们的全限定名。除了依赖auto-import="true"
以外,类也可以被显式地“import(引用)”。你甚至可以引用没有明确被映射的类和接口。 在需要查询一个特定接口的实现类或者使用一个未映射的类在hql的查询结果中时,这种方式很有用。
<import class="System.Object, System" />
<import
class="className" (1)
rename="newName" (2)
/>
(1) |
class : 任何.NET类的全限定名(或接口)。
|
(2) |
rename (可选 - 默认为类的全限定名): 在查询语句中可以使用的名字。
|
为了理解很多与持久化服务相关的.NET语言级对象的行为,我们需要把它们分为两类:
实体entity 独立于任何持有实体引用的对象。与通常的.NET模型相比,不再被引用的对象会被当作垃圾收集掉。实体必须被显式的保存和删除(除非保存和删除是从父实体向子实体引发的级联)。实体支持循环引用和交叉引用,它们也可以加上版本信息。
实体的持久化状态包含有指向其他实体的连接和一些值类型的实例。值是结构、集合、组件或者特定的不可变对象。与实体不同,值(特别是集合和组件)是通过可触及性来进行持久化和删除的。因为值对象(和结构)是随着包含它们的实体而被持久化和删除的,它们不能够被独立的加上版本信息。值没有独立的标识,所以它们不能被两个实体或者集合共享。(译者注:值还应该包含"原始类型",但文档中未提到)
所有的NHibernate类型,除了集合,都支持null语义。
直到现在,我们都一直使用"持久化对象"来代表实体。我们仍然会这么做。然而严格的来说,并不是所有用户定义的,带有持久化状态的类都是实体。组件(component)就是一个用户定义的类,仅仅由值语义构成。
基本的值类型大致可以粗糙的分为三组:System.ValueType
类型,System.Object
类型和支持大对象的System.Object
类型.和.NET类型一样,System.ValueType对应的列不能存储null
值,而System.Object可以.
表4.3 System.ValueType 映射类型
NHibernate 类型.NET 类型Database 类型备注
Boolean |
System.Boolean |
DbType.Boolean |
在没有指定类型(type ) 属性时的默认值 |
Byte |
System.Byte |
DbType.Byte |
在没有指定类型(type ) 属性时的默认值 |
Char |
System.Char |
DbType.StringFixedLength - 1 char |
在没有指定类型(type ) 属性时的默认值 |
DateTime |
System.DateTime |
DbType.DateTime -忽略毫秒 |
在没有指定类型(type ) 属性时的默认值 |
Decimal |
System.Decimal |
DbType.Decimal |
在没有指定类型(type ) 属性时的默认值 |
Double |
System.Double |
DbType.Double |
在没有指定类型(type ) 属性时的默认值 |
Guid |
System.Guid |
DbType.Guid |
在没有指定类型(type ) 属性时的默认值 |
Int16 |
System.Int16 |
DbType.Int16 |
在没有指定类型(type ) 属性时的默认值 |
Int32 |
System.Int32 |
DbType.Int32 |
在没有指定类型(type ) 属性时的默认值 |
Int64 |
System.Int64 |
DbType.Int64 |
在没有指定类型(type ) 属性时的默认值 |
PersistentEnum |
一个 System.Enum |
潜在类型对应的DbType |
不用在映射文件指定type="PersistentEnum" .而是提供枚举的程序集全名,让NHibernate用反射来猜测类型。枚举使用的潜在类型决定适当的DbType 。
|
Single |
System.Single |
DbType.Single |
在没有指定类型(type ) 属性时的默认值 |
Ticks |
System.DateTime |
DbType.Int64 |
type="Ticks" 必须被指定 |
TimeSpan |
System.TimeSpan |
DbType.Int64 |
在没有指定类型(type ) 属性时的默认值 |
Timestamp |
System.DateTime |
DbType.DateTime - 取决于数据库支持 |
type="Timestamp" 必须被指定 |
TrueFalse |
System.Boolean |
DbType.AnsiStringFixedLength - 一个字符,'T' 或者'F'
|
type="TrueFalse" 必须被指定 |
YesNo |
System.Boolean |
DbType.AnsiStringFixedLength - 一个字符,'Y' 或者'N' |
type="YesNo" 必须被指定 |
表4.4 System.Object 映射类型
NHibernate 类型.NET 类型Database 类型备注
AnsiString |
System.String |
DbType.AnsiString |
type="AnsiString" 必须被指定 |
CultureInfo |
System.Globalization.CultureInfo |
DbType.String - 表明文化(culture)的5个字符 |
在没有指定类型(type ) 属性时的默认值 |
Binary |
System.Byte[] |
DbType.Binary |
在没有指定类型(type ) 属性时的默认值 |
Type |
System.Type |
DbType.String 容纳程序集全名 |
在没有指定类型(type ) 属性时的默认值 |
String |
System.String |
DbType.String |
在没有指定类型(type ) 属性时的默认值 |
表4.5 Large Object 映射类型
NHibernate 类型.NET 类型Database 类型备注
StringClob |
System.String |
DbType.String |
type="StringClob" 必须被指定.整个字段被读入内存 |
BinaryBlob |
System.Byte[] |
DbType.Binary |
type="BinaryBlob" 必须被指定. 整个字段被读入内存 |
Serializable |
任何被标记了可序列化属性(SerializableAttribute)的System.Object .
|
DbType.Binary |
type="Serializable" 应该被指定. 如果不能为属性找到NHibernate类型,这是最后可依靠的类型。 |
要掌握NHibernate或者使用某种工具生成NHibernate的hbm.xml文件,应该了解这是一个NHibernate类型名的完整的层。type="integer"
被映射为Int32
NHibernateType,type="short"
被映射为Int16
NHibernateType.查看所有的转换你可以查看NHibernate.Type.TypeFactory
类的静态构造函数.
自定义值类型(Custom value types)
开发者创建属于他们自己的值类型也是很容易的。比如说,你可能希望持久化Int64
类型的属性,持久化成为VARCHAR
字段。NHibernate没有内置这样一种类型。自定义类型能够映射一个属性(或集合元素)到不止一个数据库表字段。比如说,你可能有这样的属性:Name {get; set;}
,这是String
类型的,对应的持久化到三个字段:FIRST_NAME
, INITIAL
, SURNAME
。
要实现一个自定义类型,可以实现NHibernate.IUserType
或NHibernate.ICompositeUserType
中的任一个,并且使用类型的全限定类名来声明属性。请查看NHibernate.DomainModel.DoubleStringType
这个例子,看看它是怎么做的。
<property name="TwoStrings" type="NHibernate.DomainModel.DoubleStringType, NHibernate.DomainModel">
<column name="first_string"/>
<column name="second_string"/>
</property>
注意使用<column>
标签来把一个属性映射到多个字段的做法。
虽然NHibernate内置的丰富类型和对component的支持意味着你可能很少需要使用自定义类型,至少对于你程序中经常出现的自定义类(并非实体)来说,这是一种好方法。比如说,MonetoryAmount
(价格总额)对比使用ICompositeUserType
来说更好,虽然它可以很容易的使用一个component实现。这样做的动机之一是抽象。通过自定义类型,以后假若你改变表示金额值的方法时,你的映射文件不需要更改,这就得到了保护。
你可强制NHibernate在生成的SQL中把标识符用引号前后包围起来,这需要在映射文档中使用反向引号(`)把表名或者字段名包围(可能比较拗口,请看下面的例子)。NHibernate会使用相应的SQLDialect
(方言)来使用正确的引号风格(通常是双引号,但是在SQL Server中是括号,MySQL中是反向引号)。
<class name="LineItem" table="`Line Item`">
<id name="id" column="`Item Id`">
<generator class="assigned"/>
</id>
<property name="itemNumber" column="`Item #`"/>
...
</class>
映射文件的模块化(Modular mapping files)
允许在独立的映射文档中定义subclass
和joined-subclass
,直接位于hibernate-mapping
下。这就可以让你每次扩展你的类层次的时候,加入新的映射文件就行了。在子类的映射中你必须指定一个extends
属性,指明先前已经映射过的超类。如果你使用嵌入的资源(Embedded Resources)配置NHibernate, hbm.xml文件会自动配置为正确的顺序.如果手动添加或者在cfg.xml文件中指定它们,映射文件的排序是非常重要的!
<hibernate-mapping>
<subclass name="Eg.Subclass.DomesticCat, Eg" extends="Eg.Cat, Eg" discriminator-value="D">
<property name="Name" type="String"/>
</subclass>
</hibernate-mapping>
分享到:
相关推荐
NObject O/R Mapping 框架包含了 OQL.NET,一套基于 C# 和 VB.NET 等原生 .NET 语言的强类型对象查询语言 (OQL, Object Query Language) 使您甚至不需要写一行 SQL 语句。 ??NObject O/R Mapping 框架能帮您减少 30...
O/R_Mapping思想与ADO.NET 基于.NET的Web应用框架的设计与实现 将对象映射到关系数据库——对象/关系映射(O/R_Mapping)详解 面向对象设计中的O/R映射架构
### Hibernate与O/R Mapping框架详解 #### 一、O/R Mapping概述 O/R Mapping(Object-Relational Mapping)即对象关系映射,是一种程序技术,用于将对象模型表示的应用程序对象与关系数据库中的表进行相互转换。在...
在Java编程语言中,O/R Mapping(对象关系映射)是一种技术,用于将数据库中的关系数据映射到对象模型上,使得开发人员可以更方便地处理数据,而无需直接操作SQL语句。在这个示例中,我们将探讨如何利用泛型和反射来...
**Hibernate O/R Mapping 入门工程包** 在Java开发领域,Hibernate是一个强大的对象关系映射(Object-Relational Mapping,简称ORM)框架,它能够帮助开发者将数据库操作转化为面向对象的编程,从而降低了数据库和...
组件出版于 2012 年末横空出世,由于不会炒作,...我才发现原来在 2013 年时上传的 0.04 版本是不带 OR/RO Mapping 机制的。。。 想了想,还是补上 v6 这个带 OR/RO Mapping 机制的版本吧,虽然是同一时期的产物。
**Tornado O/R Mapping Engine 开源详解** Tornado O/R Mapping Engine,简称为Tornado/DB,是一款基于Java平台的对象关系映射(Object-Relational Mapping,ORM)工具。ORM技术的主要目标是通过将数据库中的数据与...
"o-x-mapping"通常指的是对象到XML的映射,它允许我们将Java对象转换为XML文档,或者从XML文档中反向创建Java对象。这种映射机制是许多框架和库的核心功能,如JAXB(Java Architecture for XML Binding)和XStream等...
2. O/R Mapping 概念:讲解什么是 O/R Mapping、为什么需要 O/R Mapping,以及 O/R Mapping 的优点和缺点。 3. 常见 O/R 框架:介绍几种常见的 O/R 框架,包括 Hibernate、Entity Framework、TopLink 等。 4. ...
1. 对象/关系映射 (O/R Mapping) 2. Hibernate 3. Hibernate同步器 (Synchronizer) 4. 示例与实践 #### O/R Mapping(对象/关系映射) - **定义**:对象/关系映射是一种编程技术,用于将对象模型中的数据自动转换...
本讲座主要围绕Hibernate这一强大的对象/关系映射(O/R Mapping)框架展开,旨在帮助学员理解O/R Mapping原理,掌握Hibernate的使用,并能够运用到实际项目开发中。适合熟悉Java、SQL、JDBC,具备面向对象编程经验的...
**O/R Mapping(对象关系映射)详解** 在大多数现代商业应用开发项目中,开发者通常使用Java或C#等面向对象的技术构建应用程序软件,并利用关系型数据库存储数据。虽然也有用过程式语言如COBOL编写的应用,或者使用...
【hibernate入门】课程是针对熟悉Java、SQL和JDBC的开发者,旨在教授O/R Mapping原理和使用Hibernate进行实际项目开发。O/R Mapping(对象/关系映射)是将面向对象的软件模型与关系数据库之间的映射技术,旨在解决...
Hibernate是Java领域中一款流行的持久化框架,它实现了对象关系映射(O/R Mapping),将复杂的数据库操作转化为对Java对象的操作,从而简化了开发过程。本文主要围绕Hibernate 3.2的学习笔记,涵盖其基本概念、配置...
2. **O/R Mapping**:对象关系映射,是ORM的核心概念。它通过定义规则将数据库表映射为类,表中的字段映射为类的属性,从而实现对象与数据库记录的对应。这样,开发者可以直接操作对象,而无需关心底层SQL语句的编写...
Hibernate的底层实现是基于O/R Mapping(对象关系映射)的原理。O/R Mapping是将Java对象映射到关系型数据库表的中间层。它的目的是简化Java开发者对数据库的操作,让开发者以面向对象的方式进行数据库编程,而非...
【HIBERNATE入门】是针对Java开发者的培训资料,主要介绍了如何入门并掌握Hibernate这一流行的O/R Mapping框架。Hibernate是一种用于简化Java应用程序与数据库交互的开源库,它通过对象关系映射(O/R Mapping)技术...
Attribute O/R Mapping是一种技术,它允许开发者使用面向对象的方式来操作数据库,而无需关心底层SQL语句的编写。这种技术大大提高了开发效率,降低了代码的复杂性。 在.NET框架中,Attribute被用作一种元数据,...
【一、O/R Mapping】 O/R Mapping,即对象关系映射,是将对象模型与关系数据库之间进行映射的技术。在Hibernate中,O/R Mapping允许开发者以面向对象的方式来操作数据库,而无需关心底层的SQL语句。这极大地提高了...