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

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

我看过很多 $repo->findAll()$repo->findById($id) 示例,但我正在寻找如何扩展它以获得更复杂的读取。

例如,假设我有一个数据网格,它表示一个 SELECT 查询,其中包含多个 JOIN。我需要做这些事情:

我不确定我是否适合使用现有的 查询构建器 包,因为我不确定它的可测试性和数据库无关性(换句话说,它可能 太灵活 )。我知道我不想为这个项目使用 ORM。我正在使用 Data Mapper + Repository 方法。

我如何使用存储库模式来做到这一点?

(有时,我认为问题的 "Answer" 涉及 "lowering expectations"。)

我认为您对 "Repository Pattern" 的要求过高了。有许多第 3 方软件包试图将用户与 MySQL 隔离开来。他们通常有局限性。扩展通常是一个限制——它们不是为以复杂的方式处理庞大的数据集而设计的。

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

让我挑两个你的'requirements'。它们有利于封装,但不一定有利于存储库模式。

使用 OFFSET 和 LIMIT 进行分页...对于简单的数据集,这很好用。但我看到一个项目在他们这样做后崩溃了。他们需要明显的参数(偏移量和限制)并做了明显的事情(构造和执行 SELECT ... OFFSET $offs LIMIT $lim)。然后他们构建了一个包含 126,000 "pages" 数据的网页。然后下一步,下一步,下一步,...直到系统崩溃。

问题取决于偏移量和限制,而不是 "Next" 和 "Prev",以及 "remembering where you left off"。 (我有一篇关于那个主题的博客。)注意"solution"不能在封装的例程中执行,而是涉及UI变化和用户期望变化,加上代码。

我要评论的另一个是SQL_COUNT_FOUND_ROWS... 如此简单,如此容易。但是太致命了。就在本周,我还在为一个数据增长如此之快的人提供建议,以至于由于该计数技术而导致他遇到性能问题。许多可能的解决方案涉及的不仅仅是存储库模式。例如,典型的搜索引擎很久以前就希望获得准确的计数,而是 "managed the user expectations" 通过显示“ 大约 1,340,000 中的 10 个项目”。毫无疑问,这在很多地方使用了大量代码,而不仅仅是对一个 SQL 语句的简单增强。可能需要多台服务器。

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