1

Slick で Play フレームワークを使用するときに固定文字データベース列から値をトリミングする正しい方法と正しい場所はどこですか?

文字列を削除したい理由は、データベース スキーマが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が、オプションの値が存在しない場合は戻ります。

trim2mapはすべてのケースで機能しますが、さまざまな場所で、getForElseを使用するよりも「より慣用的な Scala」であると述べられているのを見てきましたfold

trim3現在の Scala の理解の限界を超えており、私の意図を示していますが、コンパイルされません。

の場合のコンパイルエラーtrim3は次のとおりです。

型の不一致; found : 必要なオブジェクト: play.api.libs.json.Json.JsValueWrapper

私は確かに を使用して生活することができますが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 = ""

編集:

Test2 つのフィールドを持つケース クラスである行がidありtrimMe、このクラスを JSON にマップしたいのですが、問題はtrimそれをtrimeMeフィールドにしたいことです。

がある場合Column[String]Slick観点からはオプションではないフィールドを意味しますが、ケースクラスTestはオプションのフィールドがあり、 (とTests) の両方にオプションのtrimMeフィールドがある (つまり、null 許容列を意味する) か、ない (つまり、列は必須です)。

最後に、あなたが持っているケースクラスは、データベースにある行の表現であり、それがSlickクエリが返すものです(*)。スキーマ宣言を反映する必要があります。

trim問題について

  • iftrimMeColumn[Option[String]]あなたのケースクラスにあるので、必ず a and thenを返すことtrimMe: Option[String]ができます。getOrElseStringtrim

    val someString = Option("some String  ")
    someString.getOrElse("").trim
    
  • あなたのケースのクラスがである場合trimMeは、それを でラップし、次に:Column[String]trimMe: StringOptiongetOrElsetrim

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

このようにして、例外がスローされるNoneかどうかにかかわらず、スローされます。Some

(*) 常にではありませんが、行全体ではなく列を返すクエリを使用できます。

于 2014-08-04T17:32:21.760 に答える