我有一个类似于以下内容的Slick 3.0表定义:
case class Simple(a: String, b: Int, c: Option[String])
trait Tables { this: JdbcDriver =>
import api._
class Simples(tag: Tag) extends Table[Simple](tag, "simples") {
def a = column[String]("a")
def b = column[Int]("b")
def c = column[Option[String]]("c")
def * = (a, b, c) <> (Simple.tupled, Simple.unapply)
}
lazy val simples = TableQuery[Simples]
}
object DB extends Tables with MyJdbcDriver
我希望能够做两件事:
Seq[String]
Simple
的实例,生成Seq[String]
,该Simple("hello", 1, None)
对应于使用原始查询将数据插入数据库的方式(例如Seq("'hello'", "1", "NULL")
变为let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
config.URLCache = nil // don't cache
let task = NSURLSession(configuration: config).dataTaskWithURL(...
)使用Slick表定义执行此操作的最佳方法是什么?
答案 0 :(得分:7)
<>
方法中使用Slick并更改*
运算符左侧的顺序而不更改Simple
中的值的顺序, Simples
的行类型,即Ben认为不可能的行。 ProvenShape
投影方法的*
返回类型可确保Shape
可用于在基于Column
的*和客户端类型之间进行转换,如果你写简单定义为def * = (c, b, a) <> Simple.tupled, Simple.unapply)
的{{1}},Slick会抱怨错误“找不到匹配的形状.Slick不知道如何映射给定的类型......”。因此,您可以使用 case class Simple(a: String, b: Int, c: Option[String])
迭代Simple实例的所有元素。productIterator
表,并查询元数据以获取您已有的相同信息是不明智的。您可以使用单行 Simples
获取所有列名称。请注意,表的simples.baseTableRow.create_*.map(_.name)
投影还定义了创建表模式时生成的列。因此,不会创建投影中未提及的列,并且上述语句可以保证准确返回您所需的内容而不会丢弃任何内容。简要回顾一下:
*
获取Simples表的列名列表
Seq[String]
simples.baseTableRow.create_*.map(_.name).toSeq
将使用Seq[String]
的原始查询插入到数据库中,
aSimple
使用Simple
答案 1 :(得分:1)
要获取列名称,请尝试以下操作:
db.run(for {
metaTables <- slick.jdbc.meta.MTable.getTables("simples")
columns <- metaTables.head.getColumns
} yield columns.map {_.name}) foreach println
这将打印
Vector(a, b, c)
对于案例类值,您可以使用productIterator:
Simple("hello", 1, None).productIterator.toVector
是
Vector(hello, 1, None)
您仍然需要进行值映射,并保证表中列的顺序和case类中的值相同。