2013-10-09 79 views
24

枚举值我有后续枚举:如何坚持光滑

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

我需要坚持枚举的“A”的值,但生成的SQL时,结果为0。 这是表映射:

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

如何持久枚举值?

我实现

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) 

,反而会导致:

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

,那么你需要引用您的列:

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

这是有点相关http://stackoverflow.com/questions/19030875/how-can-i-create-a-custom-column-type-with-typesafe-slick-in-scala/19040124#19040124 – cvogt

+0

这个也在Slick邮件列表上讨论https://groups.google.com/d/msg/scalaquery/Cd5iG-tJchM/fEIhq8IPVJQJ – cvogt

+0

也与http://stackoverflow.com/questions/18752929/how-to-use相关-sens-in-scala-slick – cvogt

回答

18

我个人建议从Scala的枚举类制作自己的类继承,因为你不必为你最终使用的每一个枚举创建映射器:

这里是我目前使用的光滑2.0代码:

abstract class DBEnum extends Enumeration { 

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

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

这也应光滑1.0工作(我没有测试过):

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

现在,所有你需要为你的枚举只是从DBEnum继承,它应该减少很多锅炉板。

如果要使用字符串值而不是Ints,请相应地编辑代码。

+0

tks @prakhunov,我编辑了你的答案,添加了我改为使用字符串的代码。 – Longo

+5

请注意,由于https://github.com/slick/slick/issues/540的原因,此代码似乎与当前版本无关。你会得到错误'JdbcProfile has typeInfo for type scala.slick.driver.JdbcTypesComponent $ MappedJdbcType ...'为了解决这个问题,把导入改为你特定的db驱动,而不是'jdbc'。例如'import scala.slick.driver.HsqldbDriver.simple._'和'import scala.slick.driver.HsqldbDriver。MappedJdbcType' – Luciano

+0

你是对的我注意到当我将我的项目更新到最终的slick 2.0版本时。我们最初有计划支持多个数据库,现在可能不可能。 – prakhunov

4

也许你可以为你的枚举类型创建一个TypeMapper :

​​

这样,当您从数据库加载数据时,这种方式将转换回您的枚举。如果你坚持存储你的价值观作为数据库的字符,你只需要创建一个映射到一个字符映射器和定义

+0

我实现了一个映射器,但是导致了错误: – Longo

2

一些帮助我找到了解决办法之后,枚举:

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

和表映射:

import constants.LoginStatus._ 
... 
    def stLogin = column[LoginStatus]("stlogin", O.NotNull, O.DBType("character(1)"))