Я видел много $repo->findAll()
или же $repo->findById($id)
примеры, но я ищу, как расширить это для более сложных чтений.
Например, допустим, у меня есть сетка данных, представляющая запрос SELECT с несколькими соединениями. Я собираюсь сделать следующее:
WHERE
условия, некоторые из которых происходят на JOIN
пункты запроса)SELECT *
, поэтому мне нужно указать поля, которые я хочу)Я не уверен, что мне удобно использовать существующий построитель запросов пакет, потому что я не уверен, насколько тестируемым и независимым от базы данных это будет (другими словами, это может быть слишком гибкий). Я знаю, что я не хочу использовать ORM для этого проекта. Я использую Data Mapper + Репозиторий подход вместо
Как бы я сделал это, используя шаблон репозитория?
(Иногда я полагаю, что «Ответ» на вопрос подразумевает «снижение ожиданий».)
Я полагаю, что вы слишком много просите «Шаблон хранилища». Существует много сторонних программных пакетов, которые пытаются изолировать пользователя от MySQL. У них обычно есть ограничения. Часто ограничение заключается в масштабировании — они не предназначены для работы с огромными наборами данных сложным образом.
Всякий раз, когда я использую шаблон репозитория, мне кажется, что я делаю немного больше, чем просто инкапсулирую один (или несколько) оператор SQL и помещаю инкапсулированный метод (подпрограмму) в отдельный файл. О, я верю в это. Я просто не верю в магию.
Позвольте мне выделить два ваших «требования». Они хороши для инкапсуляции, но не обязательно хороши для шаблона репозитория.
Разбивка на страницы с использованием OFFSET и LIMIT … Для простых наборов данных это работает отлично. Но я видел, как проект таял после того, как они это сделали. Они требовали очевидных параметров (смещение и предел) и делали очевидные вещи (создавали и выполняли SELECT ... OFFSET $offs LIMIT $lim
). Затем они создали веб-страницу, на которой было 126 000 «страниц» данных. Затем что-то делал Next, Next, Next, … пока система не растаяла.
Проблема заключалась в зависимости от смещения и предела вместо «Далее» и «Предыдущий», а также «запоминание, где вы остановились». (У меня есть блог на эту тему.) Обратите внимание, что «решение» не может быть выполнено в инкапсулированной подпрограмме, но включает изменения пользовательского интерфейса и ожиданий пользователя, а также код.
Другой, который я хочу прокомментировать, это SQL_COUNT_FOUND_ROWS … Так просто, так легко. Но так смертельно. Совсем недавно, на этой неделе, я советовал кому-то, чьи данные настолько выросли, что у него возникли проблемы с производительностью из-за этой техники подсчета. Многие из возможных решений включают в себя больше, чем можно застревать в шаблоне репозитория. Например, типичная поисковая система давно наказывала за получение точного количества и вместо этого «управляла ожиданиями пользователей», показывая «10 элементов из около 1340 000 «. Это, несомненно, заняло много кода во многих местах, а не просто улучшение одного оператора SQL. Возможно, потребовалось несколько серверов.
Итак, инкапсулировать — да. Шаблон репозитория — только несколько. И стать экспертом по сырому SQL.
Других решений пока нет …