在Slick表上列出列

Dan*_*her 9 scala slick

我有一个类似于以下内容的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
Run Code Online (Sandbox Code Playgroud)

我希望能做两件事:

  1. 获取列名称列表 Seq[String]
  2. 对于一个实例Simple,生成一个 Seq[String]与使用原始查询将数据插入数据库的方式相对应(例如,Simple("hello", 1, None)变为Seq("'hello'", "1", "NULL"))

使用Slick表定义执行此操作的最佳方法是什么?

Max*_*ako 7

  • 首先,不可能在方法中欺骗Slick并改变<>操作符左侧*的顺序而不改变Simple行类型中的值的顺序Simples,即Ben假设不可能的.投影方法的ProvenShape返回类型*确保Shape可以Column在*和客户端类型的基于类型之间进行转换,如果您编写了def * = (c, b, a) <> Simple.tupled, Simple.unapply)Simple定义为case class Simple(a: String, b: Int, c: Option[String]),则Slick会报错并显示"找不到匹配的形状.Slick"不知道如何映射给定的类型...".你可以用它来迭代Simple实例的所有元素productIterator.
  • 其次,您已经Simples在代码中定义了表,并查询metatable以获取您已有的相同信息是不明智的.您可以使用单行获取所有列名称simples.baseTableRow.create_*.map(_.name).请注意,*表的投影还定义了创建表模式时生成的列.因此,不会创建投影中未提及的列,并且上述语句可以保证完全返回您需要的内容,而不是删除任何内容.

简要回顾一下:

  1. 获取Simples表的列名列表作为Seq[String]使用 simples.baseTableRow.create_*.map(_.name).toSeq
  2. 生成一个Seq[String]对应于如何使用原始查询aSimple(Simple使用实例)将数据插入数据库的方法aSimple.productIterator.toSeq