代码之家  ›  专栏  ›  技术社区  ›  ps0604

在Play Slick中分配动态注入的数据库名称

  •  2
  • ps0604  · 技术社区  · 6 年前

    我有下面的打滑刀课。注意,数据库配置是一个常数 control0001 . 刀有一个功能 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") ,我需要数据库是可变的。在应用程序中,我有多个数据库( 控制0001 , control002 等等)在中配置 application.conf . 根据变量值,我需要确定DAO中要使用的数据库。所有数据库都相似,并且具有相同的表(每个数据库中的数据不同)。

    以下Play类调用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中实现这一点?

    2 回复  |  直到 6 年前
        1
  •  2
  •   cutoffurmind    6 年前

    您可以尝试初始化slick db对象,覆盖默认配置:

    val db = Database.forURL("jdbc:mysql://localhost/" + databaseName, driver="org.h2.Driver")

    slick docs中的更多信息 http://slick.lightbend.com/doc/3.0.0/database.html

        2
  •  1
  •   Jeffrey Chung    6 年前

    在这种情况下,不要尝试使用Play的运行时依赖注入实用程序,而是使用 SlickApi 直接在DAO中,并将数据源名称传递给 dbConfig(DbName(name)) 方法获得 SlickApi公司 ,混合在 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)
      ...
    }