日期:2014-05-16  浏览次数:20563 次

自定义数据类型的数据库映射方案

基础数据类型,如String、Integer、Date、Boolean等它们可以很方便的映射到数据库:

import grails.persistence.Entity

@Entity
class MyEntity {
    String code
    String name
    static constraints = {
        code(unique: true, minSize: 4, maxSize: 4)
        name(blank: false, maxSize: 255)
    }
}

这些基础数据类型是JAVA提供的语言级的,它没有语意。

比如要表达一个身份证号码:它有长度限制:15位或18位;还有规则限制;还能从身份证号码中提取出地址、性别、出生日期、年龄等信息。这些信息用一个String是无法表达,需要用类来描述:

class IDNumber{
    String idNumber

    Address address
    InsDate birthday
    Gender gender
    IDNumber() {}
    IDNumber(val) {       
        if (val.length() == 15) {
            val = to18IdNumber(val)
        }
        if (val.length() != 18) {
            throw new IllegalArgumentException("不是身份证格式")
        }
        this.idNumber = val
        return
    }
    def getAddress() {
        if (address) return address
        else return address = parseAddress()
    }
    def getBirthday() {
        if (birthday) return birthday
        else return birthday = parseBirth()
    }
    def getGender() {
        if (gender) return gender
        else return gender = parseGender()
    }
    def parseBirth() {
        ...
    }
}

这个类里面最核心的就是String idNumber身份证号码,其他属性都是暂存的临时数据,可以从身份证号码里解析出来。如果想把这个类映射到数据库中,现在只能映射成一个table,但映射成table又不合理,最好是能映射成一列:

@grails.persistence.Entity
class PersonInfo {
    String name
    IDNumber idNumber
}

现在这样显然是不能达到这个目标的。

Hibernate提供了多种实现自定义类型的方法:

1、实现org.hibernate.usertype.UserType

2、实现org.hibernate.usertype.CompositeUserType

3、实现org.hibernate.usertype.UserCollectionType

4、实现org.hibernate.usertype.EnhanceUserType

通过实现这些接口,可以将自定义数据类型映射成数据库列。

UserType可以映射成单列,CompositeUserType可以映射成多列。

看个例子:

class<