使用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
,但通常的方法是什么?
答案 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
行是一个包含两个字段id
和trimMe
的案例类,你想把这个类映射到一个JSON,但问题是你也想要trim
它是trimeMe
字段。
如果您有Column[String]
,则从Slick
角度来看,它表示非可选字段,但您的案例类具有可选字段,两者都是{{1} }}和Test
)有一个可选的Tests
字段(表示可以为空的列)或者它们不是(这意味着该列是必需的)。
最后,您拥有的案例类是您在数据库中拥有的行的表示,以及Slick查询返回的内容(*),它应该反映您的架构声明。
针对trimMe
问题
如果trim
是trimMe
您的案例类有Column[Option[String]]
,那么您可以trimMe: Option[String]
并确保返回getOrElse
然后{ {1}},
String
如果trim
是val someString = Option("some String ")
someString.getOrElse("").trim
你的案例类有trimMe
,那么只需将其打包在Column[String]
,然后trimMe: String
然后{ {1}}:
Option
通过这种方式,getOrElse
或trim
没有异常被抛出。
(*)并非总是如此,您可以使用返回列而不是整行的查询。
答案 1 :(得分:0)
模式匹配的简单逻辑怎么样:
def trimOptionString(in: Option[String]): Option[String] = in.map(_.trim) match {
case None => None
case Some("") => None
case Some(x) => Some(x)
}