我正在尝试为Scala播放应用程序实现通用CRUD特性。我正在关注this implementation.
这些我的依赖项 -
libraryDependencies ++= Seq(
"org.postgresql" % "postgresql" % "9.4-1201-jdbc41",
"com.typesafe.slick" %% "slick" % "3.0.0",
"com.typesafe.play" %% "play-slick" % "1.0.1",
"com.typesafe.play" %% "play-slick-evolutions" % "1.0.1",
"io.spray" %% "spray-json" % "1.3.2",
specs2 % Test
)
这是我的通用模型 -
package models.generic
import slick.driver.PostgresDriver.api._
import scala.concurrent.Future
abstract class GenericTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
}
trait GenericCRUD[C <: GenericTable[T], T] extends configs.DBConfig{
protected val table: TableQuery[C]
private val queryById = Compiled((id: Rep[Int]) => table.filter(_.id === id))
def all: Future[Seq[C#TableElementType]] = db.run(table.result)
def create(c: C#TableElementType): Future[Int] = db.run(table += c)
def read(id: Int): Future[Option[C#TableElementType]] = db.run(queryById(id).result.headOption)
def update(id: Int, c: C#TableElementType): Future[Int] = db.run(queryById(id).update(c))
def delete(id: Int): Future[Int] = db.run(queryById(id).delete)
}
这是使用泛型的模型实现 -
package models
import java.sql.Timestamp
import scala.concurrent.Future
import slick.driver.PostgresDriver.api._
import generic.{GenericCRUD, GenericTable}
case class Brand(id: Int, name: String, created: Timestamp, updated: Timestamp)
class BrandTable(tag: Tag) extends GenericTable[Brand](tag, "brand") {
override def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def created = column[Timestamp]("created")
def updated = column[Timestamp]("updated")
def * = (id, name, created, updated) <>((Brand.apply _).tupled, Brand.unapply)
}
object Brands extends GenericCRUD[Brand, BrandTable] {
override val table:TableQuery[Brand] = TableQuery[Brand]
}
目前我收到以下错误 -
play.sbt.PlayExceptions$CompilationException: Compilation error[type arguments [models.Brand] conform to the bounds of none of the overloaded alternatives of
value apply: [E <: slick.lifted.AbstractTable[_]]=> slick.lifted.TableQuery[E] <and> [E <: slick.lifted.AbstractTable[_]](cons: slick.lifted.Tag => E)slick.lifted.TableQuery[E]]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
at play.sbt.PlayExceptions$CompilationException$.apply(PlayExceptions.scala:27) ~[na:na]
at scala.Option.map(Option.scala:145) ~[scala-library-2.11.7.jar:na]
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:49) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$taskFailureHandler$1.apply(PlayReload.scala:44) ~[na:na]
at scala.Option.map(Option.scala:145) ~[scala-library-2.11.7.jar:na]
at play.sbt.run.PlayReload$.taskFailureHandler(PlayReload.scala:44) ~[na:na]
at play.sbt.run.PlayReload$.compileFailure(PlayReload.scala:40) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
at play.sbt.run.PlayReload$$anonfun$compile$1.apply(PlayReload.scala:17) ~[na:na]
at scala.util.Either$LeftProjection.map(Either.scala:377) ~[scala-library-2.11.7.jar:na]
at play.sbt.run.PlayReload$.compile(PlayReload.scala:17) ~[na:na]
at play.sbt.run.PlayRun$$anonfun$playRunTask$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$2.apply(PlayRun.scala:61) ~[na:na]
at play.sbt.run.PlayRun$$anonfun$playRunTask$1$$anonfun$apply$2$$anonfun$apply$3$$anonfun$2.apply(PlayRun.scala:61) ~[na:na]
at play.runsupport.Reloader$$anonfun$reload$1.apply(Reloader.scala:323) ~[na:na]
at play.runsupport.Reloader$$anon$3.run(Reloader.scala:43) ~[na:na]
at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_51]
at play.runsupport.Reloader$.play$runsupport$Reloader$$withReloaderContextClassLoader(Reloader.scala:39) ~[na:na]
at play.runsupport.Reloader.reload(Reloader.scala:321) ~[na:na]
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:113) ~[play-server_2.11-2.4.3.jar:2.4.3]
at play.core.server.DevServerStart$$anonfun$mainDev$1$$anon$1$$anonfun$get$1.apply(DevServerStart.scala:111) ~[play-server_2.11-2.4.3.jar:2.4.3]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24) ~[scala-library-2.11.7.jar:na]
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24) ~[scala-library-2.11.7.jar:na]
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:40) ~[akka-actor_2.11-2.3.13.jar:na]
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:397) ~[akka-actor_2.11-2.3.13.jar:na]
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) ~[scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) ~[scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) ~[scala-library-2.11.7.jar:na]
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107) ~[scala-library-2.11.7.jar:na]
答案 0 :(得分:2)
我发现了错误。我在GenericCRUD特征中交换了泛型类型的位置。这是更正后的版本 -
通用模型:
package models
import java.sql.Timestamp
import scala.concurrent.Future
import slick.driver.PostgresDriver.api._
import generic.{GenericCRUD, GenericTable}
case class Brand(id: Int, name: String, created: Timestamp, updated: Timestamp)
class BrandTable(tag: Tag) extends GenericTable[Brand](tag, "brand") {
override def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def created = column[Timestamp]("created")
def updated = column[Timestamp]("updated")
def * = (id, name, created, updated) <>((Brand.apply _).tupled, Brand.unapply)
}
object Brands extends GenericCRUD[BrandTable, Brand] {
override val table = TableQuery[BrandTable]
}
已实施模型:
package models.generic
import slick.driver.PostgresDriver.api._
import scala.concurrent.Future
abstract class GenericTable[T](tag: Tag, name: String) extends Table[T](tag, name) {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
}
trait GenericCRUD[C <: GenericTable[T], T] extends configs.DBConfig{
protected val table: TableQuery[C]
private val queryById = Compiled((id: Rep[Int]) => table.filter(_.id === id))
def all: Future[Seq[C#TableElementType]] = db.run(table.result)
def create(c: C#TableElementType): Future[Int] = db.run(table += c)
def read(id: Int): Future[Option[C#TableElementType]] = db.run(queryById(id).result.headOption)
def update(id: Int, c: C#TableElementType): Future[Int] = db.run(queryById(id).update(c))
def delete(id: Int): Future[Int] = db.run(queryById(id).delete)
}
答案 1 :(得分:1)
我正在使用这个CRUD实现:
LOAD DATA
INFILE 'C:\Users\Appdata\Desktop\SQl Loader\ing1.txt'
BADFILE 'C:\Users\Appdata\Desktop\SQl Loader\bad_orders.txt'
INTO TABLE Ing_Details
FIELDS
TERMINATED BY "\t"
OPTIONALLY ENCLOSED BY '"'
TRAILING NULLCOLS
(
INGREDIENT_ID NULLIF INGREDIENT_TYPE_ID=BLANKS,
INGREDIENT_TYPE_ID NULLIF INGREDIENT_TYPE_ID=BLANKS,
Status NULLIF Status=BLANKS,
Organic NULLIF Organic=BLANKS
)
我希望你喜欢它。