【问题标题】:What's the difference between using DatabaseConfig and Database in Slick?在 Slick 中使用 DatabaseConfig 和 Database 有什么区别?
【发布时间】:2016-02-25 19:23:03
【问题描述】:

我在slick's documentation 中阅读了有关DatabaseConfig 的信息:

Database 的配置语法之上,还有另一个 DatabaseConfig 形式的层,它允许您配置一个 光滑的驱动程序加上一个匹配的Database 在一起。 这很容易 通过简单地改变一个抽象的不同类型的数据库系统 配置文件.

我不明白这部分,DatabaseConfig 如何使底层数据库系统比Database 方法更抽象?假设,我在以下测试中使用DatabaseConfig

import org.scalatest.{Matchers, FlatSpec}
import slick.backend.DatabaseConfig
import slick.driver.JdbcProfile
import slick.driver.PostgresDriver.api._

import scala.concurrent.ExecutionContext.Implicits.global

class DatabaseConfigTest extends FlatSpec with Matchers {
  def withDb(test: DatabaseConfig[JdbcProfile] => Any) = {
    val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("abstract")

    try test(dbConfig)
    finally dbConfig.db.close()
  }

  "DatabaseConfig" should "work" in withDb { dbConfig =>
    import Supplier._

    val cities = suppliers.map(_.city)

    dbConfig.db.run(cities.result).map(_.foreach(println))
  }
}

如您所见,如果我将底层数据库系统从PostgreSQL 更改为MySQL,除了配置更改之外,我还需要更改将postgre API 导入mysql 的import 语句。另一方面,如果我使用的是Database

import org.scalatest.{FlatSpec, Matchers}
import slick.driver.PostgresDriver.api._
import slick.jdbc.JdbcBackend.Database

import scala.concurrent.ExecutionContext.Implicits.global

class DatabaseTest extends FlatSpec with Matchers {
  def withDb(test: Database => Any) = {
    val db = Database.forConfig("default")

    try test(db)
    finally db.close()
  }

  "Supplier names" should "be fetched" in withDb { db =>
    import Supplier._

    val names = suppliers.map(_.name)

    db.run(names.result).map(_.foreach(println))
  }
}

当我使用Database 时,对底层数据库的相同更改将导致两个更改:一个在配置文件中,另一个在源代码中。综上所述,一种方法比另一种更抽象吗?我用DatabaseConfig错了吗?

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    你很接近,但你没有正确使用DatabaseConfig。您需要导入与配置关联的驱动程序,而不是导入特定的驱动程序。像这样的东西应该可以工作:

    import org.scalatest.{Matchers, FlatSpec}
    import slick.backend.DatabaseConfig
    import slick.jdbc.JdbcProfile
    //import slick.driver.PostgresDriver.api._
    
    import scala.concurrent.ExecutionContext.Implicits.global
    
    class DatabaseConfigTest extends FlatSpec with Matchers {
      def withDb(test: DatabaseConfig[JdbcProfile] => Any) = {
        val dbConfig = DatabaseConfig.forConfig[JdbcProfile]("abstract")
    
        /* The api for the driver specified in the config is imported here. */
        import dbConfig.driver.api._  
    
        try test(dbConfig)
        finally dbConfig.db.close()
      }
    
      "DatabaseConfig" should "work" in withDb { dbConfig =>
        import Supplier._
    
        val cities = suppliers.map(_.city)
    
        dbConfig.db.run(cities.result).map(_.foreach(println))
      }
    }
    

    这应该允许您在配置中切换数据库,而无需更改任何代码或重新编译。

    【讨论】:

    • 谢谢..但是我如何在我的实体定义中使用dbConfig.driver.api._ ,例如Supplier?在这些类中,我仍然有一些特定于数据库的 import
    • 有几种不同的方法可以处理这个问题。您可以创建一个对象来保存实体定义可访问的配置对象。然后在模式实体中你可以import DbConfigHolderObject.dbConfig.driver.api._。您还可以创建一个进行设置的特征并将其混合到架构实体中。
    • 刚刚想到这个......我认为处理它的最佳方法可能是使用隐式。
    • 谢谢 DemetriKots..这是个好主意
    猜你喜欢
    • 1970-01-01
    • 2014-12-22
    • 2010-11-16
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多