8

假设我有一张桌子

object Suppliers extends Table[(Int, String, String, String)]("SUPPLIERS") {
  def id = column[Int]("SUP_ID", O.PrimaryKey)
  def name = column[String]("SUP_NAME")
  def state = column[String]("STATE")
  def zip = column[String]("ZIP")
  def * = id ~ name ~ state ~ zip
}

表的数据库名称

可以通过以下方式访问表的数据库名称:AbstractTable 上的 ScaladocSuppliers.tableName
支持这一点。

例如,上表的数据库名称是“SUPPLIERS”。

列的数据库名称

浏览AbstractTablegetLinearizedNodes看起来indexes很有希望。但是,它们的字符串表示形式中没有列名。

我假设 * 表示“我通常感兴趣的所有列”。 *是一个MappedProjection,它有这个签名:

final case class MappedProjection[T, P <: Product](
  child: Node, 
  f: (P) ⇒ T, 
  g: (T) ⇒ Option[P])(proj: Projection[P]) 
extends ColumnBase[T] with UnaryNode with Product with Serializable

*.getLinearizedNodes包含一个巨大的数字序列,我意识到此时我只是在对 API 中的所有内容进行强力检查,以便可能在字符串中找到列名。

以前有没有人遇到过这个问题,或者有人可以让我更好地了解 MappedProjection 的工作原理吗?

4

3 回答 3

3

它要求您依赖 Slick 内部结构,这可能会在版本之间发生变化,但这是可能的。以下是 Slick 1.0.1 的工作原理:您必须通过FieldSymbol. 然后你可以提取你想要的信息,就像它是如何columnInfo(driver: JdbcDriver, column: FieldSymbol): ColumnInfo做的一样。

要从 a 中获取 a FieldSymbolColumn您可以使用fieldSym(node: Node): Option[FieldSymbol]and fieldSym(column: Column[_]): FieldSymbol

于 2013-11-15T11:42:41.637 回答
2

To get the (qualified) column names you can simply do the following:

Suppliers.id.toString
Suppliers.name.toString
Suppliers.state.toString
Suppliers.zip.toString

It's not explicitly stated anywhere that the toString will yield the column name, so your question is a valid one.


Now, if you want to programmatically get all the column names, then that's a bit harder. You could try using reflection to get all the methods that return a Column[_] and call toString on them, but it wouldn't be elegant. Or you could hack a bit and get a select * SQL statement from a query like this:

val selectStatement = DB withSession {
  Query(Suppliers).selectStatement
}

And then parse our the column names.

This is the best I could do. If someone knows a better way then please share - I'm interested too ;)

于 2013-11-15T01:40:45.293 回答
2

代码基于 Lightbend Activator “slick-http-app”。

光滑版本:3.1.1

将此方法添加到 BaseDal:

def getColumns(): mutable.Map[String, Type] = {
  val columns = mutable.Map.empty[String, Type]

  def selectType(t: Any): Option[Any] = t match {
    case t: TableExpansion => Some(t.columns)
    case t: Select => Some(t.field)
    case _ => None
  }
  def selectArray(t:Any): Option[ConstArray[Node]] = t match {
    case t: TypeMapping => Some(t.child.children)
    case _ => None
  }
  def selectFieldSymbol(t:Any): Option[FieldSymbol] = t match {
    case t: FieldSymbol => Some(t)
    case _ => None
  }

  val t = selectType(tableQ.toNode)
  val c = selectArray(t.get)

  for (se <- c.get) {
    val col = selectType(se)
    val fs = selectFieldSymbol(col.get)
    columns += (fs.get.name -> fs.get.tpe)
  }
  columns
}

此方法从 TableQ 中获取列名(DB 中的真实名称)+ 类型

使用的进口是:

     import slick.ast._
     import slick.util.ConstArray
于 2016-09-22T07:24:09.970 回答