我在代码库上工作时有很多单例daos,它们使用DB.withConnection
在每个方法中从池中获取新连接,然后执行阻止。
Dao方法使用Anorm解析器来解析结果集。在某些情况下,每个dao方法在anorm解析器中运行一些其他dao方法,以获取业务模型的嵌套相关项。
我们假设你有这样的数据结构;
User -> Posts -> Comments for each posts
道如此工作;
UserDao.getUser
PostDao.getUserPosts
CommentsDao.getPostComments
因为每个dao方法都在调用DB.withConnection,所以多个连接用于简单操作。
我想使用相同的连接。可以通过implicit connection
遍历每个dao方法来完成。
但后来我需要在上层保持连接分配。现在直接从休息动作访问daos,api和dao之间没有任何类型的服务层。我觉得在api层中连接一下并不好。
所以可能有像UserService这样调用daos并处理连接和事务的服务会更好。
然后另一个要求让我感到不舒服。大多数dao方法也需要单独调用。
例如,我们只有api请求评论;
CommentsDao.getPostComments
这意味着我还需要基本上为所有daos实现Services,用DB.withConnection包装器覆盖每个dao方法,看起来像是开销。 (~30道,~10道法)
另一个限制是实际内部dao调用是在anorm解析器中完成的,我认为这是对文库的误用;
当我们将每个dao方法定义更改为传递implicit connection
时,解析器将无法编译。
因为anorm解析器是ResultSetParser[T]
,所以默认情况下无法在其中传递连接。示例解析器就像;
val apiProviderParser = get[Int]("id") ~
get[String]("product_name") ~
get[String]("description") ~
get[String]("icon_url") map {
case id ~ productName ~ desc ~ iconUrl => {
//Inner dao call
//Connection needed now
val params = getApiProviderParams(id)//(implicit connection)
new ApiProviderTemplate(id,productName,desc,iconUrl,params)
}
}
也许在范围内连接的自定义ResultSetParser [T]可以正常工作,我不确定它是解决此问题的正确方法。
我检查了蛋糕模式,dao设计问题,但无法决定如何继续以及这个问题的实用,良好的解决方案。
任何帮助表示赞赏。