在 Slick 中使用 DatabaseConfig 和 Database 有什么区别?

What's the difference between using DatabaseConfig and Database in Slick?

我正在阅读 slick's documentation 中的 DatabaseConfig

On top of the configuration syntax for Database, there is another layer in the form of DatabaseConfig which allows you to configure a Slick driver plus a matching Database together. This makes it easy to abstract over different kinds of database systems by simply changing a configuration file.

我不明白这部分,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 的。另一方面,如果我使用 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 错了吗?

你很接近,但你没有正确使用 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))
  }
}

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