2013-10-09 12 views
24

Tôi có enum sau:Làm thế nào để tồn tại giá trị enum trong trơn

object LoginStatus extends Enumeration() with BitmaskedEnumeration { 
    type LoginStatus = Value 
    val Active = Value("A") 
    val Inactive = Value("I") 
} 

tôi cần phải kiên trì giá trị của enum "A", nhưng khi sql được tạo ra kết quả là 0. đây là ánh xạ bảng:

object LoginTable extends Table[Login]("login") { 
    def idLogin = column[Int]("idlogin", O.PrimaryKey, O.AutoInc) 
    def cdLogin = column[String]("cdlogin", O.NotNull) 
    def cdPass = column[String]("cdPass", O.NotNull) 
    def stLogin = column[LoginStatus]("stlogin", O.NotNull, O.DBType("character(1)")) 
} 

làm thế nào để duy trì giá trị enum?

tôi thực hiện

implicit val charMapper = MappedTypeMapper.base[Char, String](
    b => b.toString(), 
    i => i.charAt(0)) 

    implicit def enum2StringMapper(enum: Enumeration) = MappedTypeMapper.base[enum.Value, Char](
    b => b.toString.charAt(0), 
    i => enum.withName(i.toString)) 

    implicit val LoginStatusMapper = enum2StringMapper(LoginStatus) 

nhưng cho kết quả:

[error] c.Login - Invalid value for type int : A 
+0

điều này có phần liên quan http://stackoverflow.com/questions/19030875/how-can-i-create-a-custom-column-type-with-typesafe-slick-in-scala/19040124#19040124 – cvogt

+0

Điều này cũng được thảo luận trong danh sách gửi thư của Slick https://groups.google.com/d/msg/scalaquery/Cd5iG-tJchM/fEIhq8IPVJQJ – cvogt

+0

cũng liên quan đến http://stackoverflow.com/questions/18752929/how-to-use -enums-in-scala-slick – cvogt

Trả lời

18

cá nhân tôi sẽ đề nghị làm kế thừa lớp riêng của bạn từ lớp Enumeration Scala vì sau đó bạn không cần phải tạo ra người vẽ bản đồ cho mỗi enum duy nhất bạn sẽ chỉ sử dụng:

Đây là slick 2.0 mã mà tôi hiện đang sử dụng:

abstract class DBEnum extends Enumeration { 

    import slick.jdbc.MappedJdbcType 
    import slick.driver.JdbcDriver.simple._ 

    implicit val enumMapper = MappedJdbcType.base[Value, Int](_.id, this.apply) 
} 

này cũng nên làm việc trong trơn 1.0 (tôi đã không kiểm tra nó):

abstract class DBEnum extends Enumeration { 
    implicit val enumMapper = MappedTypeMapper.base[Value, Int](_.id, this.apply) 
} 

Bây giờ tất cả bạn cần cho sự đếm của bạn chỉ là thừa kế từ DBEnum và nó sẽ cắt giảm rất nhiều đĩa nồi hơi.

Chỉnh sửa mã phù hợp nếu bạn muốn sử dụng giá trị chuỗi thay vì Ints.

+0

tks @prakhunov, tôi đã chỉnh sửa câu trả lời của bạn để thêm mã mà tôi đã thay đổi để hoạt động với chuỗi. – Longo

+5

Lưu ý rằng mã này dường như không hoạt động với bản phát hành hiện tại, do https://github.com/slick/slick/issues/540. Bạn nhận được lỗi 'JdbcProfile không có TypeInfo cho kiểu scala.slick.driver.JdbcTypesComponent $ MappedJdbcType ...' Để giải quyết vấn đề này, hãy thay đổi nhập khẩu cho trình điều khiển db cụ thể của bạn, thay vì 'jdbc'. ví dụ. 'import scala.slick.driver.HsqldbDriver.simple._' và' import scala.slick.driver.HsqldbDriver.MappedJdbcType' – Luciano

+0

Bạn đã đúng Tôi nhận thấy rằng khi tôi cập nhật dự án của mình lên bản phát hành cuối cùng 2.0 trơn. Ban đầu chúng tôi đã có kế hoạch để hỗ trợ nhiều cơ sở dữ liệu mà đáng buồn là không thể thực hiện được ngay bây giờ. – prakhunov

4

Có lẽ bạn có thể tạo ra một TypeMapper cho loại enum của bạn:

implicit val LoginStatusTypeMapper = MappedTypeMapper.base[LoginStatus.Value, Int]( 
    // conversion from LoginStatus to int 
    { 
    status => status.id 
    }, 
    // conversion back from int to enum 
    { 
    id => LoginStatus(id) 
    } 
) 

sau đó bạn cần phải tham khảo cột của bạn như :

columnLoginStatus.Value

Bằng cách này, nó sẽ được chuyển trở lại enum của bạn, khi bạn tải dữ liệu từ cơ sở dữ liệu. Nếu bạn nhấn mạnh vào lưu trữ giá trị của bạn như nhân vật trong DB, bạn chỉ cần tạo một ánh xạ mà các bản đồ đến một char và xác định trang

+0

Tôi đã triển khai một trình ánh xạ nhưng đã dẫn đến lỗi: – Longo

2

Sau khi một số giúp đỡ tôi tìm thấy giải pháp, enum:

object LoginStatus extends Enumeration { 

    def enum2StringMapper(enum: Enumeration) = MappedTypeMapper.base[enum.Value, String](
    b => b.toString, 
    i => enum.withName(i)) 

    implicit val LoginStatusMapper = enum2StringMapper(LoginStatus) 

    type LoginStatus = Value 
    val Active = Value("A") 
    val Inactive = Value("I") 
} 

và ánh xạ bảng:

import constants.LoginStatus._ 
... 
    def stLogin = column[LoginStatus]("stlogin", O.NotNull, O.DBType("character(1)")) 
Các vấn đề liên quan