我要从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