如果 table 的列数超过 22,因此它被定义为一种类型,如何使用属性名称。光滑/斯卡拉
How to use attribute names if the table has more than 22 columns so it is defined as a type. Slick / Scala
老实说,我对 Scala 和 Slick 还很陌生。
问题:我使用 Slick 2.1.0 生成了 tables.scala,对于超过 22 列的 table,我得到了 'type' 定义而不是大小写 class,这使得无法使用名称属性。
在Tables.scala...
/** Row type of table Transaction */
type TransactionRow = HCons[Int,HCons[String,HCons[Int,HCons[Int.....,HNil]...]]
/** Constructor for TransactionRow providing default values if available in the database schema. */
def TransactionRow(id: Int, code: String, placeId: Int, userId: Int, .... ): TransactionRow = {
id :: code :: placeId :: userId :: memberId .......
}
/** GetResult implicit for fetching TransactionRow objects using plain SQL queries */ .......
implicit def GetResultTransactionRow(implicit e0: GR[Int], e1: GR[String], e2: GR[java.sql.Date], e3: GR[scala.math.BigDecimal], e4: GR[Option[Int]], e5: GR[Boolean], e6: GR[java.sql.Timestamp], e7: GR[Option[String]], e8: GR[Option[Double]]): GR[TransactionRow] = GR{
prs => import prs._
<<[Int] :: <<[String] :: <<[Int] :: <<[Int] :: <<[Int] :: <<[java.sql.Date] :: <<[java.sql.Date] :: <<[scala.math.BigDecimal] :: <<[scala.math.BigDecimal] :: <<?[Int] :: <<[scala.math.BigDecimal] :: <<[String] :: <<[Boolean] :: <<[java.sql.Timestamp] :: <<[java.sql.Timestamp] :: <<[java.sql.Date] :: <<[scala.math.BigDecimal] :: <<?[String] :: <<?[Int] :: <<?[String] :: HNil
}
/** Table description of table transaction. Objects of this class serve as prototypes for rows in queries. */
class Transaction(_tableTag: Tag) extends Table[TransactionRow](_tableTag, "transaction") {
def * = id :: code :: placeId :: userId :: memberId :: .........
/** Database column id DBType(INT UNSIGNED), AutoInc, PrimaryKey */
val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
/** Database column code DBType(VARCHAR), Length(16,true) */
val code: Column[String] = column[String]("code", O.Length(16,varying=true))
...
lazy val Transaction = new TableQuery(tag => new Transaction(tag))
2) 因此我无法通过属性名称调用 TransactionRow,例如:
val x: Row = getTransactionRowFromDatabase()
println(x.code)
// x.code is not possible because this is not a case class so mapping to variable names is not possible.
3) 现在是否可以 - 例如 - 具有查询数据库的功能和 return 我可以按名称访问属性的 TransactionRow 或类似对象?
def getTransactionByCode(code: String): TransactionRow = {
val result = slickDbDef.withSession { implicit session =>
Transaction.filter(_.code === code).run
}
result(0) // This is of type TransactionRow as a result attributes are not mapped by name, instead they are a List.
// How can I make this a kind of entity I can use in my business logic?
}
我知道解决方案可能与 def * 函数有关,并且可能与我应该手动放置的附加 <> 运算符有关,但我不确定如何编写这些,因为生成的 def * 使用 :: 运算符。
提前致谢!非常感谢您的宝贵时间。
目前不支持对大于 22 的表的结果字段进行命名访问。我添加了一张票来添加这个:https://github.com/slick/slick/issues/1130
谢谢你的回答,cvogt!我喜欢将它包含在 Slick 中的想法。
如果有人遇到类似情况,我遇到了一个暂时的解决方法,将 TransactionRow 映射到一个较小的案例 class(在我们的业务逻辑中不需要所有属性的情况下,属性较少) .我相信如果我们需要所有属性,我们可以使用多案例 classes 方法,但在一个较小的示例中的想法是这样的:
case class Transaction(a:Int, b:String, c:Int)
/** Row type of table Transaction */
type TransactionRow = HCons[Int, HCons[String, HCons[Int, HNil]]]
/** Constructor for TransactionRow providing default values if available in the database schema. */
def TransactionRow(id: Int, code: String, domainId: Int): TransactionRow = {
id :: code :: domainId :: HNil
}
val x = TransactionRow(1, "TestCode", 2)
val fv:(Int :: String :: Int :: HNil) => Transaction = {
case aa :: bb :: cc :: HNil => {
Transaction(aa,bb,cc)
}
case _ => error("unknown")
}
现在我们可以将 fv 用作:
val z = fv(x)
//| z : com.viglink.batch.network.Tables.Transaction = Transaction(1,TestCode,2)
老实说,我对 Scala 和 Slick 还很陌生。
问题:我使用 Slick 2.1.0 生成了 tables.scala,对于超过 22 列的 table,我得到了 'type' 定义而不是大小写 class,这使得无法使用名称属性。
在Tables.scala...
/** Row type of table Transaction */
type TransactionRow = HCons[Int,HCons[String,HCons[Int,HCons[Int.....,HNil]...]]
/** Constructor for TransactionRow providing default values if available in the database schema. */
def TransactionRow(id: Int, code: String, placeId: Int, userId: Int, .... ): TransactionRow = {
id :: code :: placeId :: userId :: memberId .......
}
/** GetResult implicit for fetching TransactionRow objects using plain SQL queries */ .......
implicit def GetResultTransactionRow(implicit e0: GR[Int], e1: GR[String], e2: GR[java.sql.Date], e3: GR[scala.math.BigDecimal], e4: GR[Option[Int]], e5: GR[Boolean], e6: GR[java.sql.Timestamp], e7: GR[Option[String]], e8: GR[Option[Double]]): GR[TransactionRow] = GR{
prs => import prs._
<<[Int] :: <<[String] :: <<[Int] :: <<[Int] :: <<[Int] :: <<[java.sql.Date] :: <<[java.sql.Date] :: <<[scala.math.BigDecimal] :: <<[scala.math.BigDecimal] :: <<?[Int] :: <<[scala.math.BigDecimal] :: <<[String] :: <<[Boolean] :: <<[java.sql.Timestamp] :: <<[java.sql.Timestamp] :: <<[java.sql.Date] :: <<[scala.math.BigDecimal] :: <<?[String] :: <<?[Int] :: <<?[String] :: HNil
}
/** Table description of table transaction. Objects of this class serve as prototypes for rows in queries. */
class Transaction(_tableTag: Tag) extends Table[TransactionRow](_tableTag, "transaction") {
def * = id :: code :: placeId :: userId :: memberId :: .........
/** Database column id DBType(INT UNSIGNED), AutoInc, PrimaryKey */
val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
/** Database column code DBType(VARCHAR), Length(16,true) */
val code: Column[String] = column[String]("code", O.Length(16,varying=true))
...
lazy val Transaction = new TableQuery(tag => new Transaction(tag))
2) 因此我无法通过属性名称调用 TransactionRow,例如:
val x: Row = getTransactionRowFromDatabase()
println(x.code)
// x.code is not possible because this is not a case class so mapping to variable names is not possible.
3) 现在是否可以 - 例如 - 具有查询数据库的功能和 return 我可以按名称访问属性的 TransactionRow 或类似对象?
def getTransactionByCode(code: String): TransactionRow = {
val result = slickDbDef.withSession { implicit session =>
Transaction.filter(_.code === code).run
}
result(0) // This is of type TransactionRow as a result attributes are not mapped by name, instead they are a List.
// How can I make this a kind of entity I can use in my business logic?
}
我知道解决方案可能与 def * 函数有关,并且可能与我应该手动放置的附加 <> 运算符有关,但我不确定如何编写这些,因为生成的 def * 使用 :: 运算符。
提前致谢!非常感谢您的宝贵时间。
目前不支持对大于 22 的表的结果字段进行命名访问。我添加了一张票来添加这个:https://github.com/slick/slick/issues/1130
谢谢你的回答,cvogt!我喜欢将它包含在 Slick 中的想法。
如果有人遇到类似情况,我遇到了一个暂时的解决方法,将 TransactionRow 映射到一个较小的案例 class(在我们的业务逻辑中不需要所有属性的情况下,属性较少) .我相信如果我们需要所有属性,我们可以使用多案例 classes 方法,但在一个较小的示例中的想法是这样的:
case class Transaction(a:Int, b:String, c:Int)
/** Row type of table Transaction */
type TransactionRow = HCons[Int, HCons[String, HCons[Int, HNil]]]
/** Constructor for TransactionRow providing default values if available in the database schema. */
def TransactionRow(id: Int, code: String, domainId: Int): TransactionRow = {
id :: code :: domainId :: HNil
}
val x = TransactionRow(1, "TestCode", 2)
val fv:(Int :: String :: Int :: HNil) => Transaction = {
case aa :: bb :: cc :: HNil => {
Transaction(aa,bb,cc)
}
case _ => error("unknown")
}
现在我们可以将 fv 用作:
val z = fv(x)
//| z : com.viglink.batch.network.Tables.Transaction = Transaction(1,TestCode,2)