注入数据库连接池

Inject database connection pool

我已经开始使用 MacWire 为我的 Play 应用程序注入依赖项,但我在尝试注入数据库连接时遇到问题。

在使用 DI 之前,我的代码是这样的:

DB.withConnection { implicit connection =>
  ...
}

使用 DI 后这不再有效。我得到以下异常:java.lang.InstantiationException: play.api.db.DBApi.

我的应用加载器:

class Loader extends ApplicationLoader {
  def load(context: Context) = {
    val components = new BuiltInComponentsFromContext(context) with Components
    components.application
  }
}

应用程序的主要组件:

trait Components extends BuiltInComponents with I18nComponents
                 with RepositoryModule {

  lazy val assets: Assets = wire[Assets]
  lazy val router: Router = wire[Routes] withPrefix "/"
}

和存储库模块:

trait RepositoryModule {
  lazy val userRepository = wire[UserRepository]
}

如何获取和使用数据库连接池并将其注入以便在存储库中使用?

我使用 RepositoryModule 中的 DBComponentsBoneCPComponents 特征解决了它。有了它们,我可以获得一个 Database 对象,然后 将它 注入到存储库中。这是我用于模块的代码:

trait RepositoryModule extends BuiltInComponents with DBComponents with BoneCPComponents {
  lazy val database: Database = dbApi.database("default")
  lazy val userRepository = wire[UserRepository]
}

数据库 "default" 将使用 application.conf 中的 db.default 配置。此解决方案的主要问题是您需要从池中获取连接,并在完成后 return 它们。不知道能不能改进成模仿withConnection的方法

使用注入数据库的用户存储库示例:

class UserRepository(db: Database) {
  def deleteAdults: Unit = {
    val connection: Connection = db.getConnection()
    val removed: Int = SQL("DELETE * FROM User WHERE age > 18").executeUpdate()(connection)
    connection.close()
  }
}