Как сохранить значение enum в slick
У меня есть следующее перечисление:
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)
но результат:
[error] c.Login - Invalid value for type int : A
Ответы
Ответ 1
Я лично предложил бы сделать свой собственный наследование класса из класса Scala Enumeration, потому что тогда вам не нужно создавать mappers для каждого отдельного перечисления, в котором вы в конечном итоге используете:
Вот гладкий код 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)
}
Это также должно работать в slick 1.0 (я его не тестировал):
abstract class DBEnum extends Enumeration {
implicit val enumMapper = MappedTypeMapper.base[Value, Int](_.id, this.apply)
}
Теперь все, что вам нужно для ваших перечислений, это просто наследовать от DBEnum, и он должен сократить много плиты котла.
Отредактируйте код соответственно, если вы хотите использовать строковые значения вместо Ints.
Ответ 2
Возможно, вы можете создать TypeMapper для вашего типа перечисления:
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)
}
)
то вам нужно указать свой столбец как:
columnLoginStatus.Value
Таким образом, он будет преобразован обратно в ваш список, когда вы загружаете данные из базы данных. Если вы настаиваете на сохранении своих значений в качестве символов в БД, вам просто нужно создать карту, которая сопоставляется с char и определить ваш
Ответ 3
После некоторой помощи я нашел решение, перечисление:
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)"))