1

将 Play 框架与 Slick 一起使用时,从固定字符数据库列中修剪值的正确方法是什么,正确的位置在哪里?

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

我有这个案例类:

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

我有这个光滑的表关系:

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确实适用于所有情况,但我已经在各个地方看到它mapgetForElse使用fold.

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

情况下的编译错误trim3为:

类型不匹配; 找到:所需对象:play.api.libs.json.Json.JsValueWrapper

我当然可以接受 using fold,但是通常的方法是什么?

4

2 回答 2

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一行是具有两个字段的案例类,id并且trimMe您希望将此类映射到 JSON,但问题是您还希望将trim其作为trimeMe字段。

如果您有Column[String],从Slick角度来看,它意味着一个非可选字段,但您的案例类一个可选字段,或者 (TestTests) 都有一个可选trimMe字段(这意味着一个可为空的列),或者它们没有(这意味着列是强制性的)。

最后,您拥有的案例类是您在数据库中拥有的一行的表示,这就是 Slick 查询返回的(*),它应该反映您的模式声明。

对于trim问题

  • iftrimMeColumn[Option[String]]您的案例课程,trimMe: Option[String]因此您可以getOrElse并确保返回 aString然后trim

    val someString = Option("some String  ")
    someString.getOrElse("").trim
    
  • 如果你trimMeColumn[String]案例类有trimMe: String,那么只需将它包装在一个Option,然后getOrElse,然后trim

    val str = "some other string  "
    Option(str).getOrElse("").trim
    

以这种方式,无论是抛出异常None还是Some不抛出异常。

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

于 2014-08-04T17:32:21.760 回答
0

带有模式匹配的简单逻辑呢:

def trimOptionString(in: Option[String]): Option[String] = in.map(_.trim) match {
  case None => None
  case Some("") => None
  case Some(x) => Some(x)
}
于 2018-06-18T13:28:30.987 回答