ITEEDU

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。