Связывание моделей Eloquent
Сейчас мы с вами разберем связывание моделей Eloquent. Суть связывания в следующем: если у нас есть несколько таблиц, связанных друг с другом, то при запросе к одной из таблиц, Laravel будет вытягивать соответствующие данные из другой.
Пример: есть таблица cities с городами и таблица countries со странами. При этом каждый город принадлежит какой-то стране. В базе данных такая принадлежность задается полем country_id в таблице с городами.
Если использовать чистые SQL запросы, то для получения городов вместе со странами придется использовать JOIN.
Используя возможности фреймворка, получение связанных данных становится очень простым и удобным. Без сомнения, связывание моделей во фреймворках — одно из самых больших преимуществ, позволяющих упростить разработку.
Связывание моделей хорошо описано в этом видео, рекомендую его посмотреть перед изучением документации.
Связь Один к одному hasOne
По следующей ссылке изучите раздел Один к одному (до подраздела Создание обратного отношения). Решите затем следующие задачи:
Пусть у вас есть таблица users (пользователи) с полями id, login, password и таблица profiles (профили) с полями id, name (имя), surname (фамилия), email и user_id. Свяжите эти таблицы отношением hasOne.
Получите какого-нибудь пользователя вместе с его профилем.
Получите всех пользователей вместе с их профилями, передайте полученный массив в представление и выведите на экран в виде HTML таблицы table.
Связь Один к одному belongsTo
По следующей ссылке изучите раздел Создание обратного отношения. Решите затем следующие задачи:
Пусть у вас есть таблица users (пользователи) с полями id, login, password, city_id и таблица cities (города) с полями id, name (название города). Свяжите пользователей с городами отношением belongsTo.
Получите какого-нибудь пользователя вместе с его городом.
Получите всех пользователей вместе с их городами, передайте полученный массив в представление и выведите на экран в виде HTML таблицы table.
Сделайте еще таблицу countries (страны) с полями id, name (название страны). В таблицу cities добавьте поле country_id. Свяжите города со странами отношением belongsTo.
Получите все города вместе с их странами.
Получите всех пользователей вместе с их городами и странами этих городов.
Один ко многим hasMany
По следующей ссылке изучите раздел Один ко многим. Решите затем следующие задачи:
Свяжите созданную вами таблицу countries с таблицей cities отношением hasMany.
Получите все страны вместе с их городами.
Один ко многим через hasManyThrough
По следующей ссылке изучите раздел Один ко многим. Решите затем следующие задачи:
Получите всех пользователей вместе с их странами.
Многие ко многим belongsToMany
По следующей ссылке изучите раздел Многие ко многим. Решите затем следующие задачи:
Даны продукты и категории этих продуктов. Пусть продукт может принадлежать одновременно нескольким категориям. Свяжите продукты и категории отношением belongsToMany.
Получите продукты вместе с их категориями.
Получите категории вместе с продуктами, принадлежащими этим категориям.
Ленивая и нетерпеливая (жадная) загрузка
По следующей ссылке изучите раздел Нетерпеливая загрузка. Решите затем следующие задачи:
Источник
Кастомные отношения
Или, иными словами, работа со сложными отношениями между базой данных и моделями Laravel.
Недавно мне пришлось столкнуться с проблемой производительности на одном из наших крупных Laravel-проектов. Быстро расскажу о ситуации.
Нужно, чтобы администратор мог видеть всех пользователей системы в таблице. Один из столбцов этой таблицы должен отображать активные контракты ( Contract ) для каждого пользователя ( Person ).
Отношение между Contract и Person следующее:
Не хочу тратить много времени на объяснение того, как мы пришли к этой иерархии отношений. Важно знать, как мы её используем: в Contract может быть несколько Habitants , связанных через сводную модель HabitantContract ; и каждый Habitant имеет отношение к одному Person .
Поскольку мы показываем всех пользователей, то делаем в нашем контроллере:
Это упрощенный пример. Я просто хочу, что бы вы поняли суть. В идеале наш класс ресурсов должен выглядеть так:
Обратите особое внимание на отношение Person::activeContracts . Как можно заставить это работать?
Сначала можно использовать отношение HasManyThrough , но помните, что в иерархии отношений мы находимся на 4 уровне. Кроме того, я считаю, что HasManyThrough сбивает с толку.
Мы можем запросить контракты на лету, по одному на человека. Но тогда мы сталкиваемся с проблемой n+1, так как будет выполняться дополнительный запрос на каждого пользователя. Представьте себе как это повлияет на производительность, особенно если их много.
Последнее решение, которое мне пришло на ум — загрузить всех пользователей, все контракты и вручную замапить их. В итоге именно это я и сделал, но очень чистым способом: через кастомные отношения (custom relations).
Настройка модели Person
Поскольку мы хотим, чтобы $person->activeContracts работало точно так же, как и любое другое отношение, то вот что нам нужно сделать: добавить метод отношений в нашу модель, как и любое другое отношение.
Больше здесь ничего делать не нужно. Мы, конечно, только начали, ведь нужно реализовать этот ActiveContractsRelation !
Кастомный класс отношений
К сожалению, документация по созданию собственных отношений отсутствует. К счастью, не особо много о них и нужно знать: навыки погружения в код и немного времени нам помогут. Да, IDE, тоже решает.
Глядя на существующие классы отношений в Laravel, мы узнаем, что есть одно базовое отношение, которое ими всеми управляет: Illuminate\Database\Eloquent\Relations\Relation . Что означает — нам нужно реализовать некоторые абстрактные методы.
Doc-блоки помогают нам в нашем путешествии, хотя всё равно не всегда ясно, что происходит. Но нам снова повезло — у Laravel ведь уже есть классы отношений, которые мы можем рассмотреть.
Давайте шаг за шагом построим наш кастомный класс отношений. Начнем с переопределения конструктора и добавления тайпхинтов к существующим свойствам. Просто чтобы убедиться, что система типов убережет нас от глупых ошибок.
Абстрактный конструктор Relation требуется как для eloquent-класса Builder , так и для родительской модели, к которой относится отношение. Builder предназначен для использования в качестве базового объекта запроса для связанной модели Contract , в нашем случае.
Поскольку мы создаем класс отношений специально под себя, то нет необходимости настраивать конструктор. Вот как он выглядит:
Обратите внимание, что добавляем $query как к Contract так и к классу Builder . Это позволяет IDE обеспечить лучший автокомплит, например кастомные скоупы, определенные в классе модели.
Мы сделали наше отношение: оно будет запрашивать модели Contract и использовать модель Person качестве родителя. Переходим к построению нашего запроса.
Вот откуда метод addConstraints . Он будет использоваться для настройки базового запроса. Настроит наш запрос отношений по нашим потребностям. Это место, где будет основная бизнес-логика:
- Нам нужны только активные контракты
- Мы хотим загружать только активные контракты, которые принадлежат указанному лицу ( $parent нашего отношения)
- Возможно мы захотим использовать жадную загрузку для некоторых отношений, но об этом позже
Вот как выглядит addContraints на данный момент:
Я думаю, что вы знаете как работает команда join . Подытожу, что здесь происходит: мы создаем запрос, который загрузит все contracts и их habitants через сводную таблицу contract_habitants , отсюда и две команды join .
Еще одно ограничение заключается в том, что нужны только активные контракты, для этого мы можем просто использовать скоуп модели Contract .
Время добавить настоящую магию: поддержка жадной загрузки. Вот где выигрыш производительности: вместо того, чтобы делать по запросу на пользователя для загрузки его контрактов, мы делаем один запрос для загрузки всех контрактов и связываем эти контракты с нужными пользователями.
Для этого используются addEagerConstraints , initRelation и match . Давайте посмотрим на них по очереди.
Сначала метод addEagerConstraints . Он позволяет нам модифицировать запрос для загрузки всех контрактах, связанных с нужными пользователями. Помните, что мы хотим сделать только два запроса, а потом связать их результаты.
Поскольку мы уже джойнили таблицу habitants , то этот метод довольно прост: мы загружаем только те контракты, которые принадлежат предоставленной группе людей.
Далее initRelation . Опять же, всё довольно просто: его цель — инициализировать пустое отношение activeContract в каждой модели Person , чтобы впоследствии его можно было заполнить.
Обратите внимание, что свойство $this->related устанавливается родительским классом Relation , это чистый экземпляр модели нашего базового запроса, другими словами пустая модель Contract :
Наконец, мы приходим к основной функции, которая решит нашу проблему: объединение всех пользователей и контрактов вместе.
Давайте посмотрим, что здесь происходит: с одной стороны, у нас есть массив родительских моделей, пользователей; с другой стороны, у нас есть коллекция контрактов, результат запроса, выполненного нашим классом отношений. Цель функции match — связать их вместе.
Как это сделать? Все не так уж и сложно: перебрать в цикле всех пользователей и найти все контракты, принадлежащие каждому из них, на основе habitants , связанных с этим контрактом.
Готово? Ну… есть еще одна проблема. Поскольку мы используем отношение $contract->habitants , то мы должны убедиться, что оно также загружено жадно, в противном случае мы просто передвинули проблему n+1, вместо ее решения. Итак, вернемся к методу addEagerConstraints .
Добавляем вызов with для жадой загруки habitants и обратите внимание на select . Мы должны указать сборщику запросов Laravel, выбирать данные только из таблицы contracts , иначе связанные данные habitants будут объединены в модели Contract , что приведет к неправильным идентификаторам.
Наконец, нам нужно реализовать метод getResults , который просто выполняет запрос:
Вот и всё! Наше кастомное отношение может использоваться, как и любое другое отношение в Laravel. Элегантное решение сложной проблемы в стиле Laravel.
Наш Телеграм-канал — следите за новостями о Laravel.
Задать вопросы по урокам можно на нашем форуме.
Источник
Конструктор запросов
Query Builder → Community +1 015 31 мая 2015
Введение
Конструктор запросов Laravel предоставляет удобный, выразительный интерфейс для создания и выполнения запросов к базе данных. Он может использоваться для выполнения большинства типов операций и работает со всеми поддерживаемыми СУБД .
Конструктор запросов Laravel использует привязку параметров к запросам средствами PDO для защиты вашего приложения от SQL-инъекций. Нет необходимости экранировать строки перед их передачей в запрос.
Получение результатов
Получение всех записей таблицы
Используйте метод PHP table () фасада DB для создания запроса. Метод PHP table () возвращает экземпляр конструктора запросов для данной таблицы, позволяя вам «прицепить» к запросу дополнительные условия и в итоге получить результат методом PHP get () :
Метод PHP get () возвращает объект Illuminate\Support\Collection (для версии 5.2 и ранее — массив) c результатами, в котором каждый результат — это экземпляр PHP-объекта StdClass . Вы можете получить значение каждого столбца, обращаясь к столбцу как к свойству объекта:
Получение одной строки/столбца из таблицы
Если вам необходимо получить только одну строку из таблицы БД, используйте метод PHP first () . Этот метод вернёт один объект StdClass :
Если вам не нужна вся строка, вы можете извлечь одно значение из записи методом PHP value () . Этот метод вернёт значение конкретного столбца:
Получение списка всех значений одного столбца
Если вы хотите получить массив значений одного столбца, используйте метод PHP pluck () . В этом примере мы получим коллекцию (для версии 5.2 и ранее — массив) названий ролей:
Вы можете указать произвольный ключ для возвращаемой коллекции (для версии 5.2 и ранее — массива):
Если вы хотите получить массив значений одного столбца, используйте метод PHP lists () . В этом примере мы получим массив названий ролей:
Вы можете указать произвольный ключ для возвращаемого массива:
Получение результатов из таблицы «по кускам»
Если вам необходимо обработать тысячи записей БД, попробуйте использовать метод PHP chunk () . Этот метод получает небольшой «кусок» результатов за раз и отправляет его в замыкание для обработки. Этот метод очень полезен для написания Artisan-команд, которые обрабатывают тысячи записей. Например, давайте обработаем всю таблицу users «кусками» по 100 записей:
Вы можете остановить обработку последующих «кусков» вернув false из замыкания:
Агрегатные функции
Конструктор запросов содержит множество агрегатных методов, таких как count, max, min, avg и sum. Вы можете вызывать их после создания своего запроса:
Разумеется, вы можете комбинировать эти методы с другими условиями:
Выборка ( SELECT )
Указание столбцов для выборки
Само собой, не всегда вам необходимо выбрать все столбцы из таблицы БД. Используя метод PHP select () вы можете указать необходимые столбцы для запроса:
Метод PHP distinct () позволяет вернуть только отличающиеся результаты:
Если у вас уже есть экземпляр конструктора запросов и вы хотите добавить столбец к существующему набору для выборки, используйте метод PHP addSelect () :
Сырые выражения
Иногда вам может понадобиться использовать уже готовое SQL-выражение в вашем запросе. Такие выражения вставляются в запрос напрямую в виде строк, поэтому будьте внимательны и не допускайте возможностей для SQL-инъекций! Для создания сырого выражения используйте метод PHP DB :: raw () :
Объединения ( JOIN )
Объединение INNER JOIN
Конструктор запросов может быть использован для объединения данных из нескольких таблиц через PHP JOIN . Для выполнения обычного объединения «inner join» , используйте метод PHP join () на экземпляре конструктора запросов. Первый аргумент метода PHP join () — имя таблицы, к которой необходимо присоединить другие, а остальные аргументы указывают условия для присоединения столбцов. Как видите, вы можете объединять несколько таблиц одним запросом:
Объединение LEFT JOIN
Для выполнения объединения «left join» вместо «inner join» , используйте метод PHP leftJoin () . Этот метод имеет ту же сигнатуру, что и метод PHP join () :
Объединение CROSS JOIN
Для выполнения объединения CROSS JOIN используйте метод PHP crossJoin () с именем таблицы, с которой нужно произвести объединение. CROSS JOIN формирует таблицу перекрестным соединением (декартовым произведением) двух таблиц:
Сложные условия объединения
Вы можете указать более сложные условия для объединения. Для начала передайте замыкание вторым аргументом метода PHP join () . Замыкание будет получать объект JoinClause , позволяя вам указать условия для объединения:
Если вы хотите использовать стиль «where» для ваших объединений, то можете использовать для этого методы PHP where () и PHP orWhere () . Вместо сравнения двух столбцов эти методы будут сравнивать столбец и значение:
Слияние ( UNION )
Конструктор запросов позволяет создавать слияния двух запросов вместе. Например, вы можете создать начальный запрос и с помощью метода PHP union () слить его со вторым запросом:
Также существует метод PHP unionAll () с аналогичными параметрами.
Условия WHERE
Простые условия WHERE
Для добавления в запрос условий where используйте метод PHP where () на экземпляре конструктора запросов. Самый простой вызов PHP where () требует три аргумента. Первый — имя столбца. Второй — оператор (любой из поддерживаемых базой данных). Третий — значение для сравнения со столбцом.
Например, вот запрос, проверяющий равенство значения столбца «votes» и 100:
Для удобства, если вам необходимо просто проверить равенство значения столбца и данного значения, вы можете передать значение сразу вторым аргументом метода PHP where () :
Разумеется, вы можете использовать различные другие операторы при написании условия where :
В функцию PHP where () также можно передать массив условий:
Условия ИЛИ
Вы можете сцепить вместе условия where , а также условия or в запросе. Метод PHP orWhere () принимает те же аргументы, что и метод PHP where () :
Дополнительные условия WHERE
В интервале
Метод PHP whereBetween () проверяет, что значения столбца находится в указанном интервале:
Вне интервала
Метод PHP whereNotBetween () проверяет, что значения столбца находится вне указанного интервала:
Фильтрация по совпадению с массивом значений
Метод PHP whereIn () проверяет, что значения столбца содержатся в данном массиве:
Метод PHP whereNotIn () проверяет, что значения столбца не содержатся в данном массиве:
Поиск неустановленных значений ( NULL )
Метод PHP whereNull () проверяет, что значения столбца равны PHP NULL :
Метод PHP whereNotNull () проверяет, что значения столбца не равны PHP NULL :
whereDate / whereMonth / whereDay / whereYear
Метод PHP whereDate () служит для сравнения значения столбца с датой:
Метод PHP whereMonth () служит для сравнения значения столбца с месяцем в году:
Метод PHP whereDay () служит для сравнения значения столбца с днём месяца:
Метод PHP whereYear () служит для сравнения значения столбца с указанным годом:
Динамические условия WHERE
Вы можете использовать даже «динамические» условия where для гибкого построения операторов, используя магические методы:
whereColumn
Для проверки на совпадение двух столбцов можно использовать метод PHP whereColumn () :
В метод также можно передать оператор сравнения:
В метод PHP whereColumn () также можно передать массив с несколькими условиями. Эти условия будут объединены оператором AND :
Группировка условий
Иногда вам нужно сделать выборку по более сложным параметрам, таким как «существует ли» или вложенная группировка условий. Конструктор запросов Laravel справится и с такими запросами. Для начала посмотрим на пример группировки условий в скобках:
Как видите, передав замыкание в метод PHP orWhere () , мы дали конструктору запросов команду, начать группировку условий. Замыкание получит экземпляр конструктора запросов, который вы можете использовать для задания условий, поместив их в скобки. Приведённый пример выполнит такой SQL-запрос:
Проверка на существование
Метод PHP whereExists () позволяет написать SQL-условие where exists . Метод PHP whereExists () принимает в качестве аргумента замыкание, которое получит экземпляр конструктора запросов, позволяя вам определить запрос для помещения в условие «exists» :
Этот пример выполнит такой SQL-запрос:
JSON фильтрация ( WHERE )
Laravel также поддерживает запросы для столбцов типа JSON в тех БД, которые поддерживают тип столбцов JSON. На данный момент это MySQL 5.7 и Postgres. Для запроса JSON столбца используйте оператор -> :
Упорядочивание, группировка, предел и смещение
orderBy
Метод PHP orderBy () позволяет вам отсортировать результат запроса по заданному столбцу. Первый аргумент метода PHP orderBy () — столбец для сортировки по нему, а второй — задаёт направление сортировки и может быть либо asc , либо desc :
latest / oldest
Методы PHP latest () и PHP oldest () позволяют легко отсортировать результаты по дате. По умолчанию выполняется сортировка по столбцу created_at . Или вы можете передать имя столбца для сортировки по нему:
inRandomOrder
Для сортировки результатов запроса в случайном порядке можно использовать метод PHP inRandomOrder () . Например, вы можете использовать этот метод для выбора случайного пользователя:
groupBy / having / havingRaw
Методы PHP groupBy () и PHP having () используются для группировки результатов запроса. Сигнатура метода PHP having () аналогична методу PHP where () :
Метод PHP havingRaw () используется для передачи сырой строки в условие having . Например, мы можем найти все филиалы с объёмом продаж выше $2,500:
skip / take
Для ограничения числа возвращаемых результатов из запроса или для пропуска заданного числа результатов в запросе используются методы PHP skip () и PHP take () :
Или вы можете использовать методы PHP limit () и PHP offset () :
Условное применение условий
Иногда необходимо применять условие к запросу, только если выполняется какое-то другое условие. Например, выполнять оператор PHP where , только если нужное значение есть во входящем запросе. Это можно сделать с помощью метода PHP when () :
Метод PHP when () выполняет данное замыкание, только когда первый параметр равен PHP true . Если первый параметр равен PHP false , то замыкание не будет выполнено.
Вы можете передать ещё одно замыкание третьим параметром метода PHP when () . Это замыкание будет выполнено, если первый параметр будет иметь значение PHP false . Для демонстрации работы этой функции мы используем её для настройки сортировки по умолчанию для запроса:
Вставка ( INSERT )
Конструктор запросов предоставляет метод PHP insert () для вставки записей в таблицу БД. Метод PHP insert () принимает массив имён столбцов и значений:
Вы можете вставить в таблицу сразу несколько записей одним вызовом PHP insert () , передав ему массив массивов, каждый из которых — строка для вставки в таблицу:
Автоинкрементные ID
Если в таблице есть автоинкрементный ID, используйте метод PHP insertGetId () для вставки записи и получения её ID:
При использовании метода PHP insertGetId () для PostgreSQL автоинкрементное поле должно иметь имя PHP id . Если вы хотите получить ID из другого поля таблицы, вы можете передать его имя вторым аргументом.
Обновление ( UPDATE )
Разумеется, кроме вставки записей в БД конструктор запросов может и изменять существующие строки с помощью метода PHP update () . Метод PHP update () , как и метод PHP insert () , принимает массив столбцов и пар значений, содержащих столбцы для обновления. Вы можете ограничить запрос PHP update () условием PHP where () :
Обновление JSON-столбцов
При обновлении JSON-столбцов используйте синтаксис PHP -> для обращения к нужному ключу в JSON-объекте. Эта операция поддерживается только в БД, поддерживающих JSON-столбцы:
Increment и Decrement
Конструктор запросов предоставляет удобные методы для увеличения и уменьшения значений заданных столбцов. Это просто более выразительный и краткий способ по сравнению с написанием оператора update вручную.
Оба метода принимают один обязательный аргумент — столбец для изменения. Второй аргумент может быть передан для указания, на какую величину необходимо изменить значение столбца:
Вы также можете указать дополнительные поля для изменения:
Удаление ( DELETE )
Конструктор запросов предоставляет метод PHP delete () для удаления записей из таблиц. Вы можете ограничить оператор PHP delete () , добавив условие PHP where () перед его вызовом:
Если вы хотите очистить таблицу (усечение), удалив все строки и обнулив счётчик ID, используйте метод PHP truncate () :
Усечение таблицы аналогично удалению всех её записей, а также сбросом счётчика autoincrement-полей. — прим. пер.
Пессимистическая блокировка
В конструкторе запросов есть несколько функций, которые помогают делать «пессимистическую блокировку» (pessimistic locking) для ваших операторов SELECT. Для запуска оператора SELECT с «разделяемой блокировкой» вы можете использовать в запросе метод PHP sharedLock () . Разделяемая блокировка предотвращает изменение выбранных строк до конца транзакции:
Или вы можете использовать метод PHP lockForUpdate () . Блокировка «для изменения» предотвращает изменение строк и их выбор другими разделяемыми блокировками:
Комментарии (4)
Возможно ли динамически составлять набор методов для выборки? В случае, если заранее набор условий неизвестен, я могу добавить их в RAW sql в цикле, но как реализовать добавление например where в цикле. И если в случае, если у меня только where, я могу добавить условия в массив, то если добавится LIKE, то как реализовать я уже не знаю. Есть какая нибудь информация?
Конечно поздно, но может другим понадобится. Если я правильно понял, то тебе нужно что то такое
$query = \DB::table(‘название таблицы’);
$query->where(‘что то сравниваешь’, ‘с чем то сравниваешь’);
$query->groupBy(‘id’)->get();
А как сделать чтобы выбрало где одно поле меньше другого поля в той же таблице. В Mysql запрос такого вида
Источник
Laravel. Работа с БД. Часть первая — сырой запрос
Сырой запрос (Raw Query)
У Laravel для работы с базой данных есть механизм под названием Eloquent, плюс имеется мощный конструктор запросов (Query Builder), но иногда необходимо написать просто «сырой» запрос (Raw Query). Это можно сделать с помощью фасада Illuminate\Support\Facades\DB , который имеет методы для каждого типа запроса: select , update , insert , delete и statement .
1. Выполнение запроса SELECT
Метод фасада select() позволяет выполнить SELECT запрос:
Первый аргумент метода select() — сырой SQL-запрос, второй — значения параметров для прикрепления к запросу. Обычно это значения для формирования условия WHERE . Привязка параметров обеспечивает защиту от SQL-инъекций. Метод select() возвращает массив объектов stdClass .
Вместо использования знака вопроса для привязки параметров, можно выполнить запрос, используя привязку по имени:
2. Выполнение запроса INSERT
Метод фасада insert() позволяет выполнить INSERT запрос:
3. Выполнение запроса UPDATE
Для обновления существующих записей используется метод update() , который возвращает количество изменённых записей:
4. Выполнение запроса DELETE
Для удаления записей из БД используется метод delete() , который возвращает количество изменённых записей:
5. Выполнение запроса общего типа
Некоторые запросы к БД не возвращают никаких значений. Для операций такого типа предназначен метод statement() фасада:
6. Транзакции
Для выполнения набора запросов внутри одной транзакции предназначен метод transaction() . Если в функции-замыкании произойдёт исключение, транзакция автоматически откатится. А если функция выполнится успешно, транзакция автоматически применится.
Метод transaction() принимает второй необязательный аргумент, с помощью которого задаётся число повторных попыток транзакции при возникновении взаимной блокировки. После истечения этих попыток будет выброшено исключение:
Чтобы запустить транзакцию вручную и иметь полный контроль над её откатом и применением:
Можно откатить транзакцию методом rollBack() :
Можно применить транзакцию методом commit() :
Конструктор запроса (Query Builder)
Конструктор запроса предоставляет удобный интерфейс для создания и выполнения запросов к базе данных. И может использоваться для выполнения большинства типов операций. Конструктор использует привязку параметров к запросам средствами PDO для защиты от SQL-инъекций. Нет необходимости экранировать строки перед их передачей в запрос.
1. Получение всех записей таблицы
Метод table() возвращает экземпляр конструктора запросов для данной таблицы, позволяя в дальнейшем «прицепить» к запросу дополнительные условия и в итоге получить результат методом get() .
Метод get() возвращает объект Illuminate\Support\Collection c результатами, в котором каждый результат — это экземпляр класса stdClass .
2. Получение одной строки или столбца
Метод first() возвращает одну строку таблицы базы данных в виде объекта stdClass :
Если не нужна вся строка, можно извлечь только одно значение методом value() :
Метод pluck позволяет получить массив значений одного столбца таблицы:
Можно указать произвольный ключ для возвращаемой коллекции:
3. Разделение результатов на куски
Если необходимо обработать тысячи записей БД, можно использовать метод chunk() . Этот метод получает небольшой «кусок» результатов за раз и отправляет его в замыкание для обработки. Этот метод очень полезен для написания artisan-команд, которые обрабатывают тысячи записей.
Можно остановить обработку последующих «кусков» вернув false из замыкания:
4. Использование агрегатных функций
Конструктор запросов содержит множество агрегатных методов — count() , max() , min() , avg() и sum() .
Разумеется, можно комбинировать эти методы с другими условиями:
5. Указание столбцов для выборки
Используя метод select() , можно указать, какие столбцы таблицы неодбходимо выбрать:
Метод distinct() позволяет вернуть только отличающиеся результаты:
Если уже есть экземпляр конструктора и нужно добавить столбец к существующему набору:
6. Сырые выражения
Иногда может понадобиться использовать уже готовое SQL-выражение в запросе:
7. Объединение таблиц (JOIN)
Для выполнения объединения INNER JOIN предназначен метод join() конструктора запросов. Первый аргумент метода join() — имя таблицы, которую необходимо присоединить, а остальные аргументы указывают условия для присоединения.
Таблица profiles содержит профили пользователя — те данные, которые необходимы для оформления заказа в магазине (телефон и адрес доставки). Мы получаем все заказы пользователя, объединяя таблицы users , orders и profiles . Из таблицы users берем имя и адрес почты, из таблицы profiles — номер телефона, а из таблицы orders — сумму каждого заказа. Поскольку профилей может несколько, мы берем данные из основного профиля.
Чтобы создать более сложные условия объединения таблиц, нужно передать вторым аргументом метода join() функцию-замыкание:
Это практически тот же запрос, только мы отбираем не все заказы пользователя, а только те, сумма которых больше 10000 рублей.
Для выполнения объединения LEFT JOIN предназначен метод leftJoin() , который имеет ту же сигнатуру, что и метод join() .
Источник