Tôi đã cố gắng làm cho nó hoạt động, đây là đặc điểm chung của tôi:
import scala.slick.driver.PostgresDriver
import scala.slick.driver.PostgresDriver.simple._
import path.to.RichTable
trait PostgresGeneric[T <: RichTable[A], A] {
val tableReference: TableQuery[T]
def insert(row: T#TableElementType)(implicit s: Session) =
tableReference.insert(row)
def insertAndGetId(row: T#TableElementType)(implicit s: Session) =
(tableReference returning tableReference.map(_.id)) += row
def deleteById(id: Long)(implicit s: Session): Boolean =
tableReference.filter(_.id === id).delete == 1
def updateById(id: Long, row: T#TableElementType)(implicit s: Session): Boolean =
tableReference.filter(_.id === id).update(row) == 1
def selectById(id: Long)(implicit s: Session): Option[T#TableElementType] =
tableReference.filter(_.id === id).firstOption
def existsById(id: Long)(implicit s: Session): Boolean = {
(for {
row <- tableReference
if row.id === id
} yield row).firstOption.isDefined
}
}
Ở đâu RichTable
là một lớp trừu tượng với trường id, trường này, với ràng buộc giới hạn trên rất hữu ích để lấy trường id của T#TableElementType
(xem phần này để biết thêm thông tin):
import scala.slick.driver.PostgresDriver.simple._
import scala.slick.jdbc.{GetResult => GR}
abstract class RichTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
val id: Column[Long] = column[Long]("id", O.PrimaryKey, O.AutoInc)
}
Và bảng chiến dịch của tôi bây giờ trông giống như sau:
import scala.slick.driver.PostgresDriver.simple._
import scala.slick.jdbc.{GetResult => GR}
import scala.slick.lifted.TableQuery
case class CampaignRow(id: Long, name: Option[String])
class Campaign(tag: Tag) extends RichTable[CampaignRow](tag, "campaign") {
def * = (id, name) <>(CampaignRow.tupled, CampaignRow.unapply)
def ? = (id.?, name).shaped.<>({
r => import r._; _1.map(_ => CampaignRow.tupled((_1.get, _2)))
}, (_: Any) => throw new Exception("Inserting into ? projection not supported."))
override val id: Column[Long] = column[Long]("id", O.AutoInc, O.PrimaryKey)
val name: Column[Option[String]] = column[Option[String]]("name")
}
Mô hình triển khai đặc điểm chung trông như thế này:
object CampaignModel extends PostgresGeneric[Campaign, CampaignRow] {
override val tableReference: PostgresDriver.simple.TableQuery[Tables.Campaign] =
TableQuery[Campaign]
def insertCampaign(row: CampaignRow) = {
insert(CampaignRow(0, "test"))
}
}