我正在测试Slick数据库框架。
我有一个人员和地址数据库模型,一个具有基本CRUD操作的存储库和一个人员控制器。
数据模型:
package person
import java.util.concurrent.atomic.AtomicLong
import play.api.libs.json.Json
case class Address(id: Option[Int] = None, country: String, state: String, city: String, street: String, street_number: Int, extra_info: String)
case class Person(id: Option[Int] = None, name: String, last_name: String, address_id: Int)
object Address {
implicit val addressFormat = Json.format[Address]
}
object Person {
implicit val personFormat = Json.format[Person]
}
人员资料库:
package person
import javax.inject.Inject
import play.api.db.slick.DatabaseConfigProvider
import slick.jdbc.JdbcProfile
import scala.concurrent.{ExecutionContext, Future}
class PersonRepository @Inject() (dbConfigProvider: DatabaseConfigProvider)(implicit ec: ExecutionContext) {
// We want the JdbcProfile for this provider
val dbConfig = dbConfigProvider.get[JdbcProfile]
// These imports are important, the first one brings db into scope, which will let you do the actual db operations.
// The second one brings the Slick DSL into scope, which lets you define the table and other queries.
import dbConfig._
import profile.api._
class AddressTable(tag: Tag) extends Table[Address](tag, "addresses") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def country = column[String]("country")
def state = column[String]("state")
def city = column[String]("city")
def street = column[String]("street")
def street_number = column[Int]("street_number")
def extra_info = column[String]("extra_info")
override def * = (id.?, country, state, city, street, street_number, extra_info) <> ((Address.apply _).tupled, Address.unapply)
}
private val addresses = TableQuery[AddressTable]
class PeopleTable(tag: Tag) extends Table[Person](tag, "people") {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("first_name")
def last_name = column[String]("last_name")
def address_id = column[Int]("address_id")
def address = foreignKey("address_id", address_id, addresses)(_.id)
override def * = (id.?, name, last_name, address_id) <> ((Person.apply _).tupled, Person.unapply)
}
/**
* The starting point for all queries on the people table.
*/
private val people = TableQuery[PeopleTable]
def get(id: Int) = db.run((for (person <- people if person.id === id) yield person).result.headOption)
def update(person: Person): Future[Int] = db.run(people.filter(_.id === person.id).update(person))
def delete(id: Int): Future[Int] = db.run(people.filter(_.id === id).delete)
def list(): Future[Seq[Person]] = db.run (people.result)
def add(user: Person) = db
.run(people returning people.map(_.id) += user)
.map(id => user.copy(id = Some(id)))
}
人员控制器:
package person
import javax.inject.Inject
import play.api.mvc._
import play.api.libs.json.{JsError, Json, Reads}
import scala.concurrent.ExecutionContext
class PersonController @Inject()(repo: PersonRepository, cc: ControllerComponents)(implicit ec: ExecutionContext) extends AbstractController(cc) {
/*This helper parses and validates JSON using the implicit `personReads`
above, returning errors if the parsed json fails validation.*/
def validateJson[A: Reads] = parse.json.validate(
_.validate[A].asEither.left.map(e => BadRequest(JsError.toJson(e)))
)
def list = Action.async { implicit request =>
repo.list().map { people =>
Ok(Json.toJson(people))
}
}
def get(id: Int) = Action.async {
implicit request => {
val person = repo.get(id)
person.map {
case Some(p) => Ok(Json.toJson(p))
case None => NotFound
}.recover { case ex => Conflict("Fail: " + ex.toString) }
}
}
def add() = Action(validateJson[Person]).async {
implicit request => {
val person = request.body
repo.add(person).map {
p => Ok(Json.toJson(p))
}.recover { case ex => Conflict("Fail: " + ex.toString) }
}
}
def update(id_new: Int) = Action(validateJson[Person]).async {
implicit request => {
val person = request.body.copy(id = Some(id_new))
repo.update(person).map {
p => Ok("Updated user of id: " + p)
}.recover { case ex => Conflict("Fail: "+ ex.toString) }
}
}
def delete(id: Int) = Action {
implicit request => {
repo.delete(id)
Ok("Deleted")
}
}
}
application.conf
db {
slick.dbs.default.driver = "slick.driver.MySQLDriver$"
slick.dbs.default.db.driver = "com.mysql.jdbc.Driver"
slick.dbs.default.db.url = "jdbc:mysql://localhost/3306/test"
slick.dbs.default.db.user = "root"
slick.dbs.default.db.password = "root1234"
}
问题是我收到此错误,但我不知道它来自哪里。 DB conf中似乎有问题
[error] application -
! @78en3p1cm - Internal server error, for (GET) [/] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
while locating play.api.db.slick.DatabaseConfigProvider
for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
while locating person.PersonRepository
for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
while locating person.PersonController
for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
1 error]
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:222)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:137)
at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
while locating play.api.db.slick.DatabaseConfigProvider
for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
while locating person.PersonRepository
for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
while locating person.PersonController
for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
[error] application -
! @78en3p1cm - Internal server error, for (GET) [/favicon.ico] ->
play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:
1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
while locating play.api.db.slick.DatabaseConfigProvider
for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
while locating person.PersonRepository
for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
while locating person.PersonController
for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
1 error]
at play.core.server.DevServerStart$$anon$1.reload(DevServerStart.scala:186)
at play.core.server.DevServerStart$$anon$1.get(DevServerStart.scala:124)
at play.core.server.AkkaHttpServer.handleRequest(AkkaHttpServer.scala:222)
at play.core.server.AkkaHttpServer.$anonfun$createServerBinding$1(AkkaHttpServer.scala:137)
at akka.stream.impl.fusing.MapAsync$$anon$25.onPush(Ops.scala:1194)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:519)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:482)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:378)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:585)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:469)
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
1) No implementation for play.api.db.slick.DatabaseConfigProvider was bound.
while locating play.api.db.slick.DatabaseConfigProvider
for the 1st parameter of person.PersonRepository.<init>(PersonRepository.scala:9)
while locating person.PersonRepository
for the 1st parameter of person.PersonController.<init>(PersonController.scala:9)
while locating person.PersonController
for the 3rd parameter of router.Routes.<init>(Routes.scala:33)
at play.api.inject.RoutesProvider$.bindingsFromConfiguration(BuiltinModule.scala:121):
Binding(class router.Routes to self) (via modules: com.google.inject.util.Modules$OverrideModule -> play.api.inject.guice.GuiceableModuleConversions$$anon$1)
1 error
at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:470)
at com.google.inject.internal.InternalInjectorCreator.initializeStatically(InternalInjectorCreator.java:155)
at com.google.inject.internal.InternalInjectorCreator.build(InternalInjectorCreator.java:107)
at com.google.inject.Guice.createInjector(Guice.java:99)
at com.google.inject.Guice.createInjector(Guice.java:84)
at play.api.inject.guice.GuiceBuilder.injector(GuiceInjectorBuilder.scala:185)
at play.api.inject.guice.GuiceApplicationBuilder.build(GuiceApplicationBuilder.scala:137)
at play.api.inject.guice.GuiceApplicationLoader.load(GuiceApplicationLoader.scala:21)
at play.core.server.DevServerStart$$anon$1.$anonfun$reload$3(DevServerStart.scala:174)
at play.utils.Threads$.withContextClassLoader(Threads.scala:21)