我一直在寻找如何为公共CRUD和其他类型的操作实现通用特性,我看了this和this并且指定的方法运行良好 .
我想要的是一个通用的插入方法,我的类目前看起来像这样(非泛型实现):
object CampaignModel {
val campaigns = TableQuery[Campaign]
def insert(campaign: CampaignRow)(implicit s: Session) = {
campaigns.insert(campaign)
}
}
到目前为止,我在第一个链接之后尝试了这个(通用实现):
trait PostgresGeneric[T <: Table[A], A] {
val tableReference = TableQuery[T]
def insertGeneric(row: ? What type goes here ?)(implicit s: Session) = tableReference.insert(row)
}
当我检查 insert
方法时,看起来正确的类型应该是 T#TableElementType
,但我的知识非常基本,我无法绕过类型,我尝试 T
和 A
并且编译器说classtype不符合特征那些 .
其他信息,这些表是使用光滑的表生成工具生成的
case class CampaignRow(id: Long, name: Option[String])
/** Table description of table campaign. Objects of this class serve as prototypes for rows in queries. */
class Campaign(tag: Tag) extends Table[CampaignRow](tag, "campaign") {
def * = (id, name) <>(CampaignRow.tupled, CampaignRow.unapply)
/** Maps whole row to an option. Useful for outer joins. */
def ? = (id.?, name).shaped.<>({
r => import r._; _1.map(_ => CampaignRow.tupled((_1.get, _2)))
}, (_: Any) => throw new Exception("Inserting into ? projection not supported."))
/** Database column id AutoInc, PrimaryKey */
val id: Column[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey)
/** Database column name */
val name: Column[Option[String]] = column[Option[String]]("name")
}
1 回答
我设法让它工作,这是我的通用特性:
其中
RichTable
是一个带有id字段的抽象类,这个带有上限约束对于获取T#TableElementType
的id字段很有用(有关详细信息,请参阅this):我的广告系列表现在看起来像这样:
实现通用特征的模型如下所示: