在 Play Slick 中分配动态注入的数据库名称
Assign dynamically injected database name in Play Slick
我有以下 Play Slick DAO class。请注意,数据库配置是常量 control0001
。 DAO 有一个函数 readUser
可以根据用户 ID 读取用户:
class UsersDAO @Inject()(@NamedDatabase("control0001")
protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile] {
import driver.api._
def readUser (userid: String) = {
val users = TableQuery[UserDB]
val action = users.filter(_.userid === userid).result
val future = db.run(action.asTry)
future.map{
case Success(s) =>
if (s.length>0)
Some(s(0))
else
None
case Failure(e) => throw new Exception ("Failure in readUser: " + e.getMessage)
}
}
}
我需要数据库是可变的,而不是在 @NamedDatabase("control0001")
中使用常量。在应用程序中,我在 application.conf
中配置了多个数据库(control0001
、control002
等)。根据变量值,我需要确定要在 DAO 中使用的数据库。所有的数据库都是相似的并且有相同的表(每个数据库中的数据不同)。
下面的Playclass调用了DAO函数,但是首先需要确定要注入的数据库名称:
class TestSlick @Inject()(dao: UsersDAO) extends Controller {
def test(someCode: Int, userId: String) = Action { request =>
val databaseName = if (someCode == 1) "control0001" else "control0002"
// Run the method in UsersDAO accessing the database set by databaseName
val future = dao.readUser(userId)
future.map { result =>
result match {
case Some(user) => Ok(user.firstName)
case _ => Ok("user not found")
}
}
}
}
如何在 Play Slick 中实现这一点?
您可以尝试初始化 slick db 对象覆盖默认配置:
val db = Database.forURL("jdbc:mysql://localhost/" + databaseName, driver="org.h2.Driver")
更多信息在 slick 文档中 http://slick.lightbend.com/doc/3.0.0/database.html
在这种情况下,不要尝试使用 Play 的运行时依赖注入实用程序,而是使用 SlickApi
directly in your DAO and pass the datasource name to the dbConfig(DbName(name))
method. To obtain the SlickApi
, mix in the SlickComponents
特征:
class UsersDAO extends SlickComponents {
def readUser(userid: String, dbName: String) = {
val users = TableQuery[UserDB]
val action = users.filter(_.userid === userid).result
val dbConfig = slickApi.dbConfig(DbName(dbName))
val future = dbConfig.db.run(action.asTry)
...
}
}
然后在你的控制器中:
def test(someCode: Int, userId: String) = Action { request =>
val databaseName = if (someCode == 1) "control0001" else "control0002"
val future = dao.readUser(userId, databaseName)
...
}
我有以下 Play Slick DAO class。请注意,数据库配置是常量 control0001
。 DAO 有一个函数 readUser
可以根据用户 ID 读取用户:
class UsersDAO @Inject()(@NamedDatabase("control0001")
protected val dbConfigProvider: DatabaseConfigProvider)
extends HasDatabaseConfigProvider[JdbcProfile] {
import driver.api._
def readUser (userid: String) = {
val users = TableQuery[UserDB]
val action = users.filter(_.userid === userid).result
val future = db.run(action.asTry)
future.map{
case Success(s) =>
if (s.length>0)
Some(s(0))
else
None
case Failure(e) => throw new Exception ("Failure in readUser: " + e.getMessage)
}
}
}
我需要数据库是可变的,而不是在 @NamedDatabase("control0001")
中使用常量。在应用程序中,我在 application.conf
中配置了多个数据库(control0001
、control002
等)。根据变量值,我需要确定要在 DAO 中使用的数据库。所有的数据库都是相似的并且有相同的表(每个数据库中的数据不同)。
下面的Playclass调用了DAO函数,但是首先需要确定要注入的数据库名称:
class TestSlick @Inject()(dao: UsersDAO) extends Controller {
def test(someCode: Int, userId: String) = Action { request =>
val databaseName = if (someCode == 1) "control0001" else "control0002"
// Run the method in UsersDAO accessing the database set by databaseName
val future = dao.readUser(userId)
future.map { result =>
result match {
case Some(user) => Ok(user.firstName)
case _ => Ok("user not found")
}
}
}
}
如何在 Play Slick 中实现这一点?
您可以尝试初始化 slick db 对象覆盖默认配置:
val db = Database.forURL("jdbc:mysql://localhost/" + databaseName, driver="org.h2.Driver")
更多信息在 slick 文档中 http://slick.lightbend.com/doc/3.0.0/database.html
在这种情况下,不要尝试使用 Play 的运行时依赖注入实用程序,而是使用 SlickApi
directly in your DAO and pass the datasource name to the dbConfig(DbName(name))
method. To obtain the SlickApi
, mix in the SlickComponents
特征:
class UsersDAO extends SlickComponents {
def readUser(userid: String, dbName: String) = {
val users = TableQuery[UserDB]
val action = users.filter(_.userid === userid).result
val dbConfig = slickApi.dbConfig(DbName(dbName))
val future = dbConfig.db.run(action.asTry)
...
}
}
然后在你的控制器中:
def test(someCode: Int, userId: String) = Action { request =>
val databaseName = if (someCode == 1) "control0001" else "control0002"
val future = dao.readUser(userId, databaseName)
...
}