如何使用存储库模式来处理复杂的读取(SELECTs)


How to use the Repository Pattern to handle complex Reads(SELECTs)?

我看过很多$repo->findAll()$repo->findById($id)的例子,但我正在寻找如何扩展到更复杂的Reads。

例如,假设我有一个数据网格,它表示一个SELECT查询,其中有几个JOIN

  • 排序
  • 筛选(WHERE条件,其中一些条件发生在查询的JOIN子句上)
  • 列(我不想SELECT *,所以我需要指定我想要的字段)
  • 限制(分页)
  • Count(我需要知道所有页面的总行数。也许我在单独的repo方法/查询中这样做。)

我不确定我是否适合使用现有的查询生成器包,因为我不确定它的可测试性和数据库无关性(换句话说,它可能太灵活了)。我知道我不想在这个项目中使用ORM。我使用数据映射器+存储库方法。

如何使用存储库模式来完成此操作

(有时,我认为问题的"答案"涉及"降低期望值"。)

我认为您对"存储库模式"的要求太高了。有许多第三方软件包试图将用户与MySQL隔离开来。它们通常都有局限性。通常,伸缩性是一个限制——它们不是为了以复杂的方式处理庞大的数据集而设计的。

每当我使用Repository Pattern时,我所做的似乎只是封装一个(或几个)SQL语句,并将封装的方法(子例程)放在一个单独的文件中。哦,我相信做这件事。我只是不相信魔法。

让我挑出你的两个"要求"。它们适合封装,但不一定适合Repository模式。

使用OFFSET和LIMIT进行分页。。。对于简单的数据集,这很好用。但我看到一个项目在他们这么做后就崩溃了。他们需要明显的参数(偏移和限制),并做明显的事情(构造和执行SELECT ... OFFSET $offs LIMIT $lim)。然后,他们建立了一个包含126000个"页面"数据的网页。然后发生了什么Next,Next,Next。。。直到系统熔化。

问题是取决于偏移量和限制,而不是"下一个"answers"上一个",以及"记住你停止的地方"。(我有一个关于这个主题的博客。)请注意,"解决方案"不能在封装的例程中执行,而是涉及UI更改和用户期望的更改,以及代码。

我想评论的另一个是SQL_COUNT_FOUND_ROWS。。。这么简单,这么容易。但如此致命。就在本周,我还建议一个人,他的数据增长如此之快,以至于由于这种计数技术而出现了性能问题。许多可能的解决方案所涉及的内容超出了存储库模式所能承受的范围。例如,典型的搜索引擎很久以前就热衷于获得确切的计数,相反,它通过显示"中关于1340000的10个项目"来"管理用户期望"。毫无疑问,这在很多地方都需要大量的代码,而不仅仅是对一条SQL语句的简单增强。可能需要多台服务器。

所以,封装-是的。存储库模式-只是有些许。并成为原始SQL方面的专家。