Меню

Один ко многим через hasManyThrough

Связывание моделей 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 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 формирует таблицу перекрестным соединением (декартовым произведением) двух таблиц:

Читайте также:  Таблица цветов для opengl

Сложные условия объединения

Вы можете указать более сложные условия для объединения. Для начала передайте замыкание вторым аргументом метода 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)

al_saher

vitiank

Возможно ли динамически составлять набор методов для выборки? В случае, если заранее набор условий неизвестен, я могу добавить их в RAW sql в цикле, но как реализовать добавление например where в цикле. И если в случае, если у меня только where, я могу добавить условия в массив, то если добавится LIKE, то как реализовать я уже не знаю. Есть какая нибудь информация?

Alexandr5

Конечно поздно, но может другим понадобится. Если я правильно понял, то тебе нужно что то такое
$query = \DB::table(‘название таблицы’);
$query->where(‘что то сравниваешь’, ‘с чем то сравниваешь’);
$query->groupBy(‘id’)->get();

paha333

А как сделать чтобы выбрало где одно поле меньше другого поля в той же таблице. В 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() .

Источник

Adblock
detector