⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hibernate2 参考文档之五.txt

📁 Hibernate使用说明书
💻 TXT
📖 第 1 页 / 共 4 页
字号:
 

5.2. Hibernate 的类型
5.2.1. 实体(Entities)和值(values)
为了理解很多与持久化服务相关的Java语言级对象的行为,我们需要把它们分为两类: 

实体entity 独立于任何持有实体引用的对象。与通常的Java模型相比,不再被引用的对象会被当作垃圾收集掉。实体必须被显式的保存和删除(除非保存和删除是从父实体向子实体引发的级联)。这和ODMG模型中关于对象通过可触及保持持久性有一些不同——比较起来更加接近应用程序对象通常在一个大系统中的使用方法。实体支持循环引用和交叉引用,它们也可以加上版本信息。 

实体的持久化状态包含有指向其他实体的连接和一些值 类型的实例。值是原始类型、集合、组件或者特定的不可变对象。与实体不同,值(特别是集合和组件)是通过可触及性来进行持久化和删除的。因为值对象(和原始类型数据)是随着包含它们的实体而被持久化和删除的,它们不能够被独立的加上版本信息。值没有独立的标识,所以它们不能被两个实体或者集合共享。 

所有的Hibernate对象,除了集合,都支持null语义。 

直到现在,我们都一直使用"持久化对象"来代表实体。我们仍然会这么做。然而严格的来说,并不是所有用户定义的,带有持久化状态的类都是实体。组件(component)就是一个用户定义的类,仅仅由值语义构成。 

5.2.2. 基本值类型
基本类型可以大致的分为: 

integer, long, short, float, double, character, byte, boolean, yes_no, true_false
这些类型都对应Java的原始类型或者其包装类,来适合(特定厂商的)SQL 字段类型。boolean, yes_no 和 true_false都是Java 中boolean 或者java.lang.Boolean的另外说法。 

string
从java.lang.String 到 VARCHAR (或者 Oracle的 VARCHAR2)的映射。 

date, time, timestamp
从java.util.Date和其子类到SQL类型DATE, TIME 和TIMESTAMP (或等价类型)的映射。 

calendar, calendar_date
从java.util.Calendar 到SQL 类型TIMESTAMP和 DATE(或等价类型)的映射。 

big_decimal
从java.math.BigDecimal 到 NUMERIC (或者 Oracle 的NUMBER类型)的映射。 

locale, timezone, currency
从java.util.Locale, java.util.TimeZone 和java.util.Currency 到VARCHAR (或者 Oracle 的VARCHAR2类型)的映射. Locale和 Currency 的实例被映射为它们的ISO代码。TimeZone的实例被影射为它的ID。 

class
从java.lang.Class 到 VARCHAR (或者 Oracle 的VARCHAR2类型)的映射。Class被映射为它的全限定名。 

binary
把字节数组(byte arrays)映射为对应的 SQL二进制类型。 

text
把长Java字符串映射为SQL的CLOB或者TEXT类型。 

serializable
把可序列化的Java类型映射到对应的SQL二进制类型。你也可以为一个并非默认为基本类型或者实现PersistentEnum接口的可序列化Java类或者接口指定Hibernate类型serializable。 

clob, blob
JDBC 类 java.sql.Clob 和 java.sql.Blob的映射。某些程序可能不适合使用这个类型,因为blob和clob对象可能在一个事务之外是无法重用的。(而且, 驱动程序对这种类型的支持充满着补丁和前后矛盾。) 


实体及其集合的唯一标识可以是任何基础类型,除了binary、 blob 和 clob之外。(联合标识也是允许的,后面会说到。) 

在net.sf.hibernate.Hibernate中,定义了基础类型对应的Type常量。比如,Hibernate.STRING代表string 类型。 

5.2.3. 持久化枚举(Persistent enum)类型
枚举(enumerated)类型是一种常见的Java习惯用语,它是一个类,拥有一些(不多)的不可变实例。你可以为枚举类型实现net.sf.hibernate.PersistentEnum接口,定义toInt() 和 fromInt()方法: 

package eg;
import net.sf.hibernate.PersistentEnum;

public class Color implements PersistentEnum {
    private final int code;
    private Color(int code) {
        this.code = code;
    }
    public static final Color TABBY = new Color(0);
    public static final Color GINGER = new Color(1);
    public static final Color BLACK = new Color(2);

    public int toInt() { return code; }

    public static Color fromInt(int code) {
        switch (code) {
            case 0: return TABBY;
            case 1: return GINGER;
            case 2: return BLACK;
            default: throw new RuntimeException("Unknown color code");
        }
    }
}
Hibernate可以使用枚举类的名字作为类型名,这个例子中就是eg.Color。 

5.2.4. 自定义值类型
开发者创建属于他们自己的值类型也是很容易的。比如说,你可能希望持久化java.lang.BigInteger类型的属性,持久化成为VARCHAR字段。Hibernate没有内置这样一种类型。自定义类型能够映射一个属性(或集合元素)到不止一个数据库表字段。比如说,你可能有这样的Java属性:getName()/setName(),这是java.lang.String类型的,对应的持久化到三个字段:FIRST_NAME, INITIAL, SURNAME。 

要实现一个自定义类型,可以实现net.sf.hibernate.UserType或net.sf.hibernate.CompositeUserType中的任一个,并且使用类型的Java全限定类名来声明属性。请查看net.sf.hibernate.test.DoubleStringType这个例子,看看它是怎么做的。 

<property name="twoStrings" type="net.sf.hibernate.test.DoubleStringType">
    <column name="first_string"/>
    <column name="second_string"/>
</property>
注意使用<column>标签来把一个属性映射到多个字段的做法。 

虽然Hibernate内置的丰富类型和对component的支持意味着你可能很少需要使用自定义类型,至少对于你程序中经常出现的自定义类(并非实体)来说,这是一种好方法。比如说,MonetoryAmount(价格总额)对比使用CompositeUserType来说更好,虽然它可以很容易的使用一个component实现。这样做的动机之一是抽象。通过自定义类型,以后假若你改变表示金额值的方法时,你的映射文件不需要更改,这就得到了保护。 

5.2.5. 映射到"任意"(any)类型
这是属性映射的又一种类型。<any>映射元素定义了一种从多个表到类的多形联合。这种类型的映射总是需要多于一个字段。第一个字段持有被从属的实体的类型。其他的字段持有标识符。对于这种类型的联合来说,不可能指定一个外键约束,所以当然这不是(多形)联合映射的通常方式。你只应该在非常特殊的情况下使用它(比如,审计log,用户会话数据等等)。 

<any name="anyEntity" id-type="long" meta-type="eg.custom.Class2TablenameType">
    <column name="table_name"/>
    <column name="id"/>
</any>
meta-type属性让应用程序指定一个自定义类型,把数据库字段值映射到一个持久化类,该类的标识属性是用id-type定义的。如果meta-type返回java.lang.Class的实例,不需要其他处理。另一方面,如果是类似string或者character这样的基本类型,你必须指定从值到类的映射。 

<any name="anyEntity" id-type="long" meta-type="string">
    <meta-value value="TBL_ANIMAL" class="Animal"/>
    <meta-value value="TBL_HUMAN" class="Human"/>
    <meta-value value="TBL_ALIEN" class="Alien"/>
    <column name="table_name"/>
    <column name="id"/>
</any>
<any
        name="propertyName"              
        id-type="idtypename"             
        meta-type="metatypename"         
        cascade="none|all|save-update"   
        access="field|property|ClassName"        
>
        <meta-value ... />
        <meta-value ... />
        .....
        <column .... />
        <column .... />
        .....
</any>
 name: 属性名。 
 
 id-type: 标识符类型。 
 
 meta-type (可选 - 默认为class): 一个用于把java.lang.Class映射到一个数据库字段的类或者允许分辨映射的类型。 
 
 cascade(级联) (可选- 默认为 none): 级联风格。 
 
 access (可选 - 默认是 property): Hibernate用来访问属性的策略。 
 

老式的object 类型是用来在Hibernate 1.2中起到类似作用的,他仍然被支持,但是已经基本废弃了。 

5.3. SQL中引号包围的标识符
你可强制Hibernate在生成的SQL中把标识符用引号前后包围起来,这需要在映射文档中使用反向引号(`)把表名或者字段名包围(可能比较拗口,请看下面的例子)。Hibernate会使用相应的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>
5.4. 自定义DDL
Hibernate映射文档也包含一些只为了SchemaExport命令行工具生成DDL使用的信息。比如,你可以使用<column>元素的sql-type属性覆盖字段类型。 

<property 
    name="amount" 
    type="big_decimal">
    <column 
        name="AMOUNT" 
        sql-type="NUMERIC(11, 2)"/>
</property>
或者,你可以指定字段长度和约束。下面是等价的: 

<property 
    name="socialSecurityNumber" 
    type="string" 
    length="9" 
    column="SSN"
    not-null="true" 
    unique="true"/>

<property 
    name="socialSecurityNumber" 
    type="string">
    <column 
        name="SSN" 
        length="9" 
        not-null="true" 
        unique="true"/>
</property>
最后,也可以通过SchemaExport命令行工具自动生成所需的索引。如果要这么做,请在<column>元素上使用index属性。 

<property
    name="lastname">
    <column
        name="LASTNAME"
        index="by_last_first"/>
</property>

<property
    name="firstname">
     <column
         name="FIRSTNAME"
         index="by_last_first"/>
</property>
关于SchemaExport的更多内容,请参见本文档的“工具箱”那一章。 

5.5. 映射文件的模块化(Modular mapping files)
允许在独立的映射文档中定义subclass和joined-subclass,直接位于hibernate-mapping下。这就可以让你每次扩展你的类层次的时候,加入新的映射文件就行了。在子类的映射中你必须指定一个extents属性,指明先前已经映射过的超类。使用这个功能的时候,一定要注意映射文件的排序是非常重要的! 

<hibernate-mapping>
        <subclass name="eg.subclass.DomesticCat" extends="eg.Cat" discriminator-value="D">
             <property name="name" type="string"/>
        </subclass>
</hibernate-mapping>

--------------------------------------------------------------------------------
Prev  Up  Next 
Chapter 4. 持久化类(Persistent Classes)  Home  Chapter 6. 集合类(Collections) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -