使用Anorm更好的dao设计

时间:2016-06-11 04:56:45

标签: scala anorm

我在代码库上工作时有很多单例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设计问题,但无法决定如何继续以及这个问题的实用,良好的解决方案。

任何帮助表示赞赏。

0 个答案:

没有答案