2010-09-20 151 views
15

在Grails中,有没有办法限制枚举映射到的列的大小。在以下示例中,我想列类型是CHAR(2)Grails枚举映射

enum FooStatus { 
    BAR('br'), TAR('tr') 
    final static String id 
} 

class Foo { 
    FooStatus status 

    static constraints = { 
     status(inList:FooStatus.values()*.id,size:2..2) 
    } 
} 

既INLIST和大小没有导出的模式时的任何效果,列型保持其缺省值(varch(255) ) 也许我可以这样做,如果我定义一个新的UserType。任何想法 ?

谢谢 -Ken

回答

20

我不认为这是可能直接给出枚举在GORM内部映射的方式。但代码更改为这个工程:

enum FooStatus { 
    BAR('br'), 
    TAR('tr') 
    private FooStatus(String id) { this.id = id } 
    final String id 

    static FooStatus byId(String id) { 
     values().find { it.id == id } 
    } 
} 

class Foo { 
    String status 

    FooStatus getFooStatus() { status ? FooStatus.byId(status) : null } 
    void setFooStatus(FooStatus fooStatus) { status = fooStatus.id } 

    static transients = ['fooStatus'] 

    static constraints = { 
     status inList: FooStatus.values()*.id 
    } 

    static mapping = { 
     status sqlType: 'char(2)' 
    } 
} 

添加瞬态getter和setter允许您设置或获取任何字符串(ID)或枚举值。

+0

这很烦人,我不得不为每个枚举类型添加一个getter和setter,并且还声明它为“transient”。伯特,不会自定义的UserType是一个更优雅的解决方案吗? – ken 2010-09-20 06:25:42

+0

如果您可以设置Enum的id并将id转换为调用代码中的枚举实例,那么transient和getter/setter是可选的。真正的变化是坚持一个字符串而不是Enum(这是你使用inList()的暗示,因为这对Enum来说不起作用)。但确定,一个自定义的UserType应该可以工作。如果你不止一次地这样做,你会想把常见的东西提取到基类中。如果可能的话,我希望将所有内容都保存在域类中,只要这些更改没有那么重要。 – 2010-09-20 14:17:29

+0

伯特,是的,你是对的我想能够设置和获得状态变量作为一个枚举,也能够保存数据库,因此在枚举中使用ID。我更倾向于自定义用户类型沿着mapping = {status type:EnumUserType} – ken 2010-09-20 20:46:15

11

对于枚举,Grails会附带一个未记录的(据我所知)定制的Hibernate映射。该类是org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType。它不会让您设置列大小,但可以轻松地更改每个枚举值存储在数据库中的内容,而无需向模型添加瞬态字段。

import org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType 

class MyDomainClass { 
    Status status 

    static mapping = { 
     status(type: IdentityEnumType) 
    } 

    enum Status { 
     FOO("F"), BAR("B") 
     String id 
     Status(String id) { this.id = id } 
    } 
} 

您可以运行BootStrap.groovy中的 '更改表' 缩小列:

DataSource dataSource 
... 
Sql sql = new Sql(dataSource) 
sql.execute("alter table my_domain_class change column status status varchar(1) not null") 
+0

你在说哪个版本? – genuinefafa 2014-08-18 13:02:17

+0

你在问关于Grails版本吗? 2.2.1和其他 – 2014-08-21 08:28:18

+0

为了工作,我必须在另一个文件中声明我的枚举! – lfrodrigues 2015-04-28 19:56:57

2

甚至更​​容易(工作至少Grails中2.1.0+)

class DomainClass { 
    Status status 
    static mapping = { 
     status(enumType: "string") 
    } 
} 

enum Status { 
    OPEN  ("OPEN"), 
    CLOSED ("CLOSED"), 
    ... 

    String name 
    Status (String name) { 
     this.name = name 
    } 
} 
1

由于可以启用GORM 6.1身份枚举映射这样的构造

static mapping = { 
    myEnum enumType:"identity" 
}