我们说a table:
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
}
可以通过以下方式访问表格的数据库名称:Suppliers.tableName
Scaladoc on AbstractTable支持此功能。
例如,上表的数据库名称为" SUPPLIERS"。
通过AbstractTable,getLinearizedNodes
和indexes
看起来很有希望。但是,字符串表示中没有列名称。
我认为*表示"all the columns I'm usually interested in." *
是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的工作原理吗?
答案 0 :(得分:3)
它需要您依赖Slick内部,这可能会在版本之间发生变化,但这是可能的。以下是它对Slick 1.0.1的工作原理:您必须通过FieldSymbol
。然后,您可以提取所需的信息,例如columnInfo(driver: JdbcDriver, column: FieldSymbol): ColumnInfo
如何做。
要从FieldSymbol
获取Column
,您可以使用fieldSym(node: Node): Option[FieldSymbol]
和fieldSym(column: Column[_]): FieldSymbol
。
答案 1 :(得分:2)
要获取(合格)列名称,您只需执行以下操作:
Suppliers.id.toString
Suppliers.name.toString
Suppliers.state.toString
Suppliers.zip.toString
在toString
将产生列名称的任何地方都没有明确说明,因此您的问题是有效的。
现在,如果你想以编程方式获取所有列名,那就更难了。您可以尝试使用反射来获取返回Column[_]
并在其上调用toString
的所有方法,但这不会很优雅。或者你可以破解一下,从这样的查询中获取select *
SQL语句:
val selectStatement = DB withSession {
Query(Suppliers).selectStatement
}
然后解析我们的列名。
这是我能做的最好的事情。如果有人知道更好的方式,请分享 - 我也很感兴趣;)
答案 2 :(得分:2)
代码基于Lightbend Activator&#34; slick-http-app&#34;。
光滑版本: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