【问题标题】:How to trim an option string in a Slick column mapping when using Play Scala使用 Play Scala 时如何修剪 Slick 列映射中的选项字符串
【发布时间】:2014-09-27 05:53:46
【问题描述】:

在将 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 比使用fold 是“更惯用的Scala”。

trim3 刚刚超出了我目前对 Scala 的理解的极限,显示了我的意图但无法编译。

trim3情况下的编译错误为:

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

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

【问题讨论】:

    标签: scala playframework-2.0 slick-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 的角度来看,它意味着一个非可选字段,但你的案例类一个可选字段,要么是(TestTests ) 有一个可选的trimMe 字段(这意味着一个可为空的列)或者它们没有(这意味着该列是强制性的)。

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

    对于trim问题

    • 如果trimMeColumn[Option[String]] 你的案例类有trimMe: Option[String] 所以你可以getOrElse 并确保返回String 然后trim

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

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

    这样无论是None 还是Some 都不会抛出异常。

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

    【讨论】:

    • 我认为我的问题更多地与在典型的 Play/Scala/Slick/JSON 架构中应该在何处以及如何完成它有关。从你的回答中我仍然不清楚我应该怎么做。
    • 您的编辑为我指出了解决方案,谢谢。我可以简单地做 test.trimMe.getOrElse("").trim。我以为我之前尝试过,但后来我尝试了很多不同的方法......
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2023-03-19
      • 1970-01-01
      • 2016-11-12
      • 1970-01-01
      • 2021-03-20
      • 2018-12-19
      • 1970-01-01
      • 1970-01-01
      • 2020-03-13
      相关资源
      最近更新 更多