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

邮差的信 提交于 2019-12-09 18:05:01

问题


I was reading about DatabaseConfig in slick's documentation:

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.

I don't get this part, how DatabaseConfig makes the underlying database system more abstract than the Database approach? Suppose, i'm using DatabaseConfig in the following test:

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))
  }
}

As you can see, if i change my underlying database system from PostgreSQL to MySQL, in addition to configuration change, i need to change the import statement that imports the postgre API to mysql's. On the other hand, If i was using 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))
  }
}

When i'm using Database, same change on the underlying database, would result in two changes: one in configuration file and the other in source code. With all these being said, how one approach is more abstract than the other one? Am i using DatabaseConfig wrong?


回答1:


You are close, but you aren't quite using DatabaseConfig properly. Rather than importing a specific driver, you need to import the driver associated with the config. Something like this should work:

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))
  }
}

This should allow you to switch databases in the config without having to change any code or recompile.



来源:https://stackoverflow.com/questions/35636436/whats-the-difference-between-using-databaseconfig-and-database-in-slick

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!