问题
I was reading about DatabaseConfig
in slick's documentation:
On top of the configuration syntax for
Database
, there is another layer in the form ofDatabaseConfig
which allows you to configure a Slick driver plus a matchingDatabase
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