如何在Play 2.5中依赖注入数据库



我要从2.3迁移到2.5

原来我有"DAOFactory"对象

object DAOFactory {
  def categoryDAO: CategoryDAO =  AnormCategoryDAO
  def itemDAO: ItemDAO = AnormItemDAO
  def bidDAO: BidDAO = AnormBidDAO
  def userDAO: UserDAO = AnormUserDAO
  def feedStatsDAO: FeedStatsDAO = AnormFeedStatsDAO
}

,让我们以AnormCategoryDAO为例,我必须将"对象"更改为"类"

object AnormCategoryDAO extends CategoryDAO {
  val category = {
    int("id") ~ str("display_name") ~ str("url_name") map {
      case id~displayName~urlName => Category(id, displayName, urlName)
    }
  }
  def create(displayName: String, urlName: String) = DB.withConnection { implicit c =>
    SQL("INSERT INTO category(display_name, url_name) VALUES({displayName}, {urlName})").on(
      'displayName -> displayName, 'urlName -> urlName).executeUpdate()
  }
  def findById(id: Int): Option[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category WHERE id = {id}").on('id -> id).as(category singleOpt)
  }
  def findByName(urlName: String): Option[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category WHERE url_name = {urlName}").on('urlName -> urlName).as(category singleOpt)
  }
  def all(): List[Category] = DB.withConnection { implicit c =>
    SQL("SELECT * FROM category ORDER BY display_name").as(category *)
  }
}

所以我将OBJECT改为CLASS,并像下面那样用SINGLETON注释,并且我更改了"DB"。连接到数据库。withConnection "

@Singleton
class AnormCategoryDAO @Inject()(db: Database) extends CategoryDAO {
  val category = {
    int("id") ~ str("display_name") ~ str("url_name") map {
      case id~displayName~urlName => Category(id, displayName, urlName)
    }
  }
...

现在,"AnormCategoryDAO"是一个类。因此,我需要找出一种方法来实例化它与默认数据库。但是我不知道如何实例化它。

object DAOFactory {
  //def categoryDAO: CategoryDAO = AnormCategoryDAO
  def userDAO: UserDAO = AnormUserDAO
  def itemDAO: ItemDAO = AnormItemDAO
}

问题是,我如何注入数据库并实例化它?

我不喜欢使用guice或类似于di。对于编译时di,我可以使用如下命令来实现:

import play.api.db.slick.{DbName, SlickComponents}
trait TablesComponents extends BaseComponent with SlickComponents {
  lazy val dbConf = api.dbConfig[JdbcProfile](DbName("default"))
  lazy val myTable = new MyTable(dbConf.db)
  lazy val otherTable = new OtherTable(dbConf.db)
}

你要么已经准备好了要注入的依赖,在这种情况下你可以直接调用new AnormCategoryDAO(myDb),或者你在需要的地方注入AnormCategoryDAO(这可能意味着依赖注入会一直传播到由Play实例化的控制器)。

例如:

class CategoryService @Inject() (categoryDao: CategoryDAO) {
  def findAll() = categoryDao.findAll()
}

请注意,在本例中,我使用抽象类型CategoryDAO来指代categoryDAO。为此,你必须告诉依赖注入框架(通常是Guice)它应该注入哪个具体类(绑定)。或者,您也可以直接依赖AnormCategoryDAO

如何定义自定义绑定的文档在这里:https://www.playframework.com/documentation/2.5.x/ScalaDependencyInjection

请注意,还有一种替代依赖注入的方法,名为编译时:https://www.playframework.com/documentation/2.5.x/ScalaCompileTimeDependencyInjection

最新更新