2010-09-20 155 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" 
}