使用Play Scala时如何修剪Slick列映射中的选项字符串

时间:2014-08-04 17:14:59

标签: scala playframework-2.0 slick-2.0

使用Play框架和Slick时,修正固定字符数据库列中的值是正确的方法和正确的位置是什么?

我想修剪字符串的原因是数据库模式指定了character(40)列类型而不是character varying类型。

我有这个案例类:

case class Test(id: Long, trimMe: Option[String])

我有这个Slick表关系:

class Tests(tag: Tag) extends Table[Test](tag, "test") {

  def id     = column[Long  ]("test_id", O.PrimaryKey, O.AutoInc)
  def trimMe = column[String]("trim_me"                         )

  def * = (id, trimMe) <> (Test.tupled, Test.unapply _)

}

我有一个带有JSON映射的测试类:

object TrimTest {

  implicit val testWrite = new Writes[Test] {
    def writes(test: Test) = Json.obj(
      "id"   -> test.id    ,
      "trim" -> test.trimMe
    )}
}

这一切都有效,但会返回一个空格填充的字符串。

我在JSON映射器中尝试了一些修剪变体:

object TrimTest {

  implicit val testWrite = new Writes[Test] {
    def writes(test: Test) = Json.obj(
      "id"    -> test.id                              ,
      "trim1" -> test.trimMe.map(_.trim)              ,
      "trim2" -> test.trimMe.fold("") {_.trim}        ,
      "trim3" -> test.trimMe.map(_.trim).getOrElse("")
    )}
}
上面的

trim1有效,但当可选值不存在时会返回null

trim2适用于所有情况,但我已经看到它在不同的地方声明map然后getForElse是“更惯用的Scala”而不是fold。< / p>

trim3刚刚超出我目前对Scala的理解限制并显示了我的意图,但没有编译。

trim3的情况下的编译错误是:

  

类型不匹配;   发现:对象   必需:play.api.libs.json.Json.JsValueWrapper

我当然可以使用fold,但通常的方法是什么?

2 个答案:

答案 0 :(得分:1)

如何获得价值然后修剪?

scala> val strOpt = Option("Some string not trimmed    ")
strOpt: Option[String] = Some(Some string not trimmed    )

scala> strOpt.getOrElse("").trim
res0: String = Some string not trimmed

scala> val strNone = Option(null)
strNone: Option[Null] = None

scala> strNone.getOrElse("").trim
res2: String = ""

编辑:

你有一个Test行是一个包含两个字段idtrimMe的案例类,你想把这个类映射到一个JSON,但问题是你也想要trim它是trimeMe字段。

如果您有Column[String],则从Slick角度来看,它表示非可选字段,但您的案例类具有可选字段,两者都是{{1} }}和Test)有一个可选的Tests字段(表示可以为空的列)或者它们不是(这意味着该列是必需的)。

最后,您拥有的案例类是您在数据库中拥有的行的表示,以及Slick查询返回的内容(*),它应该反映您的架构声明。

针对trimMe问题

  • 如果trimtrimMe您的案例类有Column[Option[String]],那么您可以trimMe: Option[String]并确保返回getOrElse然后{ {1}},

    String
  • 如果trimval someString = Option("some String ") someString.getOrElse("").trim 你的案例类有trimMe,那么只需将其打包在Column[String],然后trimMe: String然后{ {1}}:

    Option

通过这种方式,getOrElsetrim没有异常被抛出。

(*)并非总是如此,您可以使用返回列而不是整行的查询。

答案 1 :(得分:0)

模式匹配的简单逻辑怎么样:

def trimOptionString(in: Option[String]): Option[String] = in.map(_.trim) match {
  case None => None
  case Some("") => None
  case Some(x) => Some(x)
}