How to persist enum value in slick

醉酒当歌 提交于 2019-12-03 05:40:57

问题


I have the follow enum:

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

I need to persist the value of the enum "A", but when the sql is generated the result is 0. this is the table mapping:

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

how to persiste the enum value?

I implemented

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)

but result in:

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

回答1:


I would personally suggest making your own class inherit from Scala's Enumeration class because then you don't have to create mappers for every single enum you end up using:

Here is the slick 2.0 code that I am currently using:

abstract class DBEnum extends Enumeration {

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

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

This should also work in slick 1.0 ( I have not tested it ):

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

Now all you need for your enums is just to inherit from DBEnum and it should cut down on a lot of boiler plate.

Edit the code accordingly if you want to use string values instead of Ints.




回答2:


Maybe you could create a TypeMapper for your enum type:

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

then you need to reference your column as:

columnLoginStatus.Value

This way it will be transformed back to your enum, when you load data from the database. If you insist on storing your values as characters in the DB, you just need to create a mapper that maps to a char and define your




回答3:


After some help I found the solution, the 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")
}

and the table mapping:

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


来源:https://stackoverflow.com/questions/19273805/how-to-persist-enum-value-in-slick

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!