gpt4 book ai didi

postgresql - Slick 2.0 通用 CRUD 操作

转载 作者:行者123 更新时间:2023-11-29 11:21:08 25 4
gpt4 key购买 nike

我一直在寻找如何为公共(public) CRUD 和其他类型的操作实现通用特征,我查看了 thisthis并且指定的方法运行良好。

我想要的是一个通用的插入方法,我的类目前看起来像这样(非通用实现):

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 但我的知识很基础,我无法理解类型,我尝试了 TA 并且编译器说类类型不符合 trait one 的。

其他信息,表格是用 slick 表格生成工具生成的

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")
}

最佳答案

我设法让它发挥作用,这是我的一般特征:

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
}
}

其中 RichTable 是一个带有 id 字段的抽象类,带有上限约束的这个对于获取 T#TableElementType 的 id 字段很有用(参见 this更多信息):

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)
}

我的事件表现在看起来像这样:

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")
}

实现通用特征的模型如下所示:

 object CampaignModel extends PostgresGeneric[Campaign, CampaignRow] {

override val tableReference: PostgresDriver.simple.TableQuery[Tables.Campaign] =
TableQuery[Campaign]

def insertCampaign(row: CampaignRow) = {
insert(CampaignRow(0, "test"))
}
}

关于postgresql - Slick 2.0 通用 CRUD 操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23345303/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com