2010-09-20 6 views
15

trong Grails, Có cách nào giới hạn kích thước của cột mà enum được ánh xạ hay không. Trong ví dụ sau, tôi muốn các loại cột là char (2)Grails Enum Mapping

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

class Foo { 
    FooStatus status 

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

cả inList và kích thước không có bất kỳ tác dụng khi xuất khẩu các lược đồ, các loại cột giữ giá trị mặc định của nó (varch (255)) Có lẽ tôi có thể làm điều đó nếu tôi định nghĩa một UserType mới. Bất kỳ ý tưởng ?

Cảm ơn bạn -ken

Trả lời

20

Tôi không nghĩ rằng đó là trực tiếp có thể đưa ra cách đếm được ánh xạ nội bộ trong GORM. Nhưng thay đổi mã này hoạt động:

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)' 
    } 
} 

Thêm getter và setter thoáng cho phép bạn thiết lập hoặc lấy một trong hai String (id) hoặc giá trị enum.

+0

Thật khó chịu khi tôi phải thêm vào mọi loại enum một trình gỡ rối và trình cài đặt và cũng khai báo là "tạm thời". Burt, một UserType tùy chỉnh có phải là giải pháp thanh lịch hơn không? – ken

+0

Tạm thời và getter/setter là tùy chọn nếu bạn đồng ý với việc thiết lập id của Enum và chuyển id thành thể hiện enum trong mã gọi. Sự thay đổi thực sự là sự bền bỉ của một String thay vì Enum (nó đã được ngụ ý bởi việc bạn sử dụng inList() vì nó sẽ không hoạt động với Enum anyway). Nhưng chắc chắn, một UserType tùy chỉnh sẽ hoạt động. Bạn muốn trích xuất các công cụ phổ biến vào một lớp cơ sở nếu bạn làm điều này nhiều lần. Sở thích của tôi là giữ mọi thứ trong lớp miền nếu có thể, miễn là những thay đổi đó không quan trọng. –

+0

Burt, có bạn đúng tôi muốn có thể thiết lập và nhận được biến trạng thái như là một enum và cũng có thể lưu cơ sở dữ liệu do đó việc sử dụng id trong enum. Tôi đang nghiêng về phía một người dùng tùy chỉnh loại một cái gì đó dọc theo bản đồ = {loại trạng thái: EnumUserType} – ken

11

Grails tàu với một không có giấy tờ (như xa như tôi có thể nói anyway) tùy chỉnh Hibernate lập bản đồ cho enums. Lớp này là org.codehaus.groovy.grails.orm.hibernate.cfg.IdentityEnumType. Nó sẽ không cho phép bạn đặt kích thước cột nhưng làm cho nó dễ dàng để thay đổi những gì được lưu trữ trong DB cho mỗi giá trị enum mà không cần phải thêm các trường thoáng qua cho mô hình của bạn.

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 } 
    } 
} 

Bạn có thể chạy một 'thay đổi bảng' trong Bootstrap.groovy để thu nhỏ cột:

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

bạn đang nói về phiên bản nào? – genuinefafa

+0

Bạn đang hỏi về phiên bản Grails? 2.2.1 và những người khác –

+0

Tôi đã phải khai báo enum của tôi trong một tập tin khác để làm việc! – lfrodrigues

2

Thậm chí dễ dàng hơn (chỉ hoạt động ít nhất trong 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

Vì bản đồ liệt kê nhận dạng bản đồ GORM 6.1 có thể được bật như vậy, hãy xây dựng

static mapping = { 
    myEnum enumType:"identity" 
}