我已经开始使用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]
}
如何获取和使用数据库连接池并将其注入,以便可以在存储库中使用?
答案 0 :(得分:2)
我使用DBComponents
中的BoneCPComponents
和RepositoryModule
特征解决了这个问题。有了它们,我可以获得一个Database
对象并将它注入到存储库。这是我用于模块的代码:
trait RepositoryModule extends BuiltInComponents with DBComponents with BoneCPComponents {
lazy val database: Database = dbApi.database("default")
lazy val userRepository = wire[UserRepository]
}
数据库“default”将使用db.default
中的application.conf
配置。此解决方案的主要问题是您需要从池中获取连接并在完成后返回它们。我不知道是否可以改进模仿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()
}
}