创建表查询时,我想通过映射默认表查询来修改我的select语句。但是,我找不到映射列值并仍然映射到我的案例类的方法
case class MyRecord(id: Int, name: String, value: Int) class MyTable(tag: Tag) extends Table[MyRecord](tag, "MYTABLE") { def id = column[Int]("id") def name = column[String]("name") def value = column[Int]("value") def * = (id, name, value) <> (MyRecord.tupled, MyRecord.unapply) } lazy val tableQuery = TableQuery[MyTable]
我想name用此函数调整值:
name
def trimLeading0: (Rep[String]) => Rep[String] = SimpleExpression.unary[String, String] { (str, queryBuilder) => import slick.util.MacroSupport._ import queryBuilder._ b"TRIM(LEADING 0 FROM $str)" }
现在,我对这里的操作一无所知:
val trimmedTableQuery: Query[MyTable, MyRecord, Seq] = tableQuery.map(s => ???)
我已经尝试过映射,Rep就像处理case类一样:
Rep
val trimmedTableQuery = tableQuery.map(s => s.copy(name = trimLeading0(s.name)))
这拒绝与 value copy is not a member of MyTable
value copy is not a member of MyTable
我当前的解决方法是使用自定义函数,而不是使用MyRecord.tupled默认投影:
MyRecord.tupled
def trimming(t: (Int, String, Int)) = MyRecord(t._1, t._2.dropWhile(_ == "0"), t._3) def * = (id, name, value) <> (trimming, MyRecord.unapply)
另外,我可以将返回DBIOAction元组的返回结果映射到case类,这不太优雅:
DBIOAction
val action = tableQuery.map{ s => (s.id, trimLeading0(s.name), s.value)}.result val futureTuples: Future[Seq[(Int, String, Int)]] = db.run(action) val records = futureTuples map (s => s.map(MyRecord.tupled))
但是map在构建查询时如何在方法内部进行操作?还是更改def name列说明会更好?
map
def name
您不能弄乱MyTable中的默认投影(即def *),因为它需要对称。用于查询和插入。但是,您可以基于MyTable的特殊化(带有覆盖的默认投影)创建trimmedTableQuery。然后,您还可以使用基于对称默认投影的tableQuery。如果您尝试基于trimmedTableQuery进行插入,则会收到错误消息(但您不必这样做,只需使用tableQuery进行插入)。
lazy val tableQuery = TableQuery[MyTable] lazy val trimmedTableQuery = new TableQuery(new MyTable(_) { override def * = (id, trimLeading0(name), value) <> (MyRecord.tupled, MyRecord.unapply) })