Может войдёшь?
Черновики Написать статью Профиль

Конструктор запросов

перевод документация 5.х

  1. 1. Введение
  2. 2. Получение результатов
    1. 2.1. Агрегатные функции
  3. 3. Выборка (SELECT)
  4. 4. Объединения (JOIN)
  5. 5. Слияние (UNION)
  6. 6. Условия WHERE
    1. 6.1. Сложная фильтрация (WHERE)
    2. 6.2. JSON фильтрация (WHERE)
  7. 7. Упорядочивание, группировка, предел и смещение
  8. 8. Условные операторы
  9. 9. Вставка (INSERT)
  10. 10. Обновление (UPDATE)
  11. 11. Удаление (DELETE)
  12. 12. Пессимистическая блокировка
Этот перевод актуален для англоязычной документации на (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Конструктор запросов предоставляет удобный, выразительный интерфейс для создания и выполнения запросов к базе данных. Он может использоваться для выполнения большинства типов операций и работает со всеми поддерживаемыми СУБД.

Конструктор запросов Laravel использует привязку параметров к запросам средствами PDO для защиты вашего приложения от SQL-инъекций. Нет необходимости экранировать строки перед их передачей в запрос.

Получение результатов

Получение всех записей таблицы

Для начала создания запроса используйте метод PHPtable() фасада DB. Метод PHPtable() возвращает экземпляр конструктора запросов для данной таблицы, позволяя вам «прицепить» к запросу дополнительные условия и в итоге получить результат. В данном примере давайте просто получим PHPget() все записи из таблицы:

PHP
<?php

namespace App\Http\Controllers;

use 
DB;
use 
App\Http\Controllers\Controller;

class 
UserController extends Controller
{
  
/**
   * Показать список всех пользователей приложения.
   *
   * @return Response
   */
  
public function index()
  {
    
$users DB::table('users')->get();

    return 
view('user.index', ['users' => $users]);
  }
}

Подобно сырым запросам метод PHPget() возвращает массив результатов, в котором каждый результат — это экземпляр PHP-объекта StdClass. Вы можете получить значение каждого столбца, обращаясь к столбцу как к свойству объекта:

PHP
foreach ($users as $user) {
  echo 
$user->name;
}

Получение одной строки/столбца из таблицы

Если вам необходимо получить только одну строку из таблицы БД, используйте метод PHPfirst(). Этот метод вернёт один объект StdClass:

PHP
$user DB::table('users')->where('name''John')->first();

echo 
$user->name;

Если вам не нужна вся строка, вы можете извлечь одно значение из записи методом PHPvalue(). Этот метод вернёт значение конкретного столбца:

PHP
$email DB::table('users')->where('name''John')->value('email');

Получение результатов из таблицы «по кускам»

Если вам необходимо обработать тысячи записей БД, попробуйте использовать метод PHPchunk(). Этот метод получает небольшой «кусок» результатов за раз и отправляет его в замыкание для обработки. Этот метод очень полезен для написания Artisan-команд, которые обрабатывают тысячи записей. Например, давайте обработаем всю таблицу users «кусками» по 100 записей:

PHP
DB::table('users')->orderBy('id')->chunk(100, function($users) {
  foreach (
$users as $user) {
    
//
  
}
});

Вы можете остановить обработку последующих «кусков» вернув false из замыкания:

PHP
DB::table('users')->orderBy('id')->chunk(100, function($users) {
  
// Обработка записей...

  
return false;
});

Получение списка всех значений одного столбца

+ 5.2

добавлено в 5.2 ()

Если вы хотите получить массив значений одного столбца, используйте метод PHPpluck(). В этом примере мы получим массив названий ролей:

PHP
$titles DB::table('roles')->pluck('title');

foreach (
$titles as $title) {
  echo 
$title;
}

Вы можете указать произвольный ключ для возвращаемого массива:

PHP
$roles DB::table('roles')->pluck('title''name');

foreach (
$roles as $name => $title) {
  echo 
$title;
}
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Если вы хотите получить массив значений одного столбца, используйте метод PHPlists(). В этом примере мы получим массив названий ролей:

PHP
$titles DB::table('roles')->lists('title');

foreach (
$titles as $title) {
  echo 
$title;
}

Вы можете указать произвольный ключ для возвращаемого массива:

PHP
$roles DB::table('roles')->lists('title''name');

foreach (
$roles as $name => $title) {
  echo 
$title;
}

Агрегатные функции

Конструктор запросов содержит множество агрегатных методов, таких как count, max, min, avg и sum. Вы можете вызывать их после создания своего запроса:

PHP
$users DB::table('users')->count();

$price DB::table('orders')->max('price');

Разумеется, вы можете комбинировать эти методы с другими условиями для создания вашего запроса:

PHP
$price DB::table('orders')
                ->
where('finalized'1)
                ->
avg('price');

Выборка (SELECT)

Указание столбцов для выборки

Само собой, не всегда вам необходимо выбрать все столбцы из таблицы БД. Используя метод PHPselect() вы можете указать необходимые столбцы для запроса:

PHP
$users DB::table('users')->select('name''email as user_email')->get();

Метод PHPdistinct() позволяет вернуть только отличающиеся результаты:

PHP
$users DB::table('users')->distinct()->get();

Если у вас уже есть экземпляр конструктора запросов и вы хотите добавить столбец к существующему набору для выборки, используйте метод PHPaddSelect():

PHP
$query DB::table('users')->select('name');

$users $query->addSelect('age')->get();

Сырые выражения

Иногда вам может понадобиться использовать уже готовое SQL-выражение в вашем запросе. Такие выражения вставляются в запрос напрямую в виде строк, поэтому будьте внимательны и не допускайте возможностей для SQL-инъекций! Для создания сырого выражения используйте метод PHPDB::raw():

PHP
$users DB::table('users')
                     ->
select(DB::raw('count(*) as user_count, status'))
                     ->
where('status''<>'1)
                     ->
groupBy('status')
                     ->
get();

Объединения (JOIN)

Объединение INNER JOIN

Конструктор запросов может быть использован для объединения данных из нескольких таблиц через PHPJOIN. Для выполнения обычного SQL-объединения «inner join», используйте метод PHPjoin() на экземпляре конструктора запросов. Первый аргумент метода PHPjoin() — имя таблицы, к которой необходимо присоединить другие, а остальные аргументы указывают условия для присоединения столбцов. Как видите, вы можете объединять несколько таблиц одним запросом:

PHP
$users DB::table('users')
            ->
join('contacts''users.id''=''contacts.user_id')
            ->
join('orders''users.id''=''orders.user_id')
            ->
select('users.*''contacts.phone''orders.price')
            ->
get();

Объединение LEFT JOIN

Для выполнения объединения «left join» вместо «inner join», используйте метод PHPleftJoin(). Этот метод имеет ту же сигнатуру, что и метод PHPjoin():

PHP
$users DB::table('users')
            ->
leftJoin('posts''users.id''=''posts.user_id')
            ->
get();
+ 5.2

добавлено в 5.2 ()

Объединение CROSS JOIN

Для выполнения объединения CROSS JOIN используйте метод PHPcrossJoin() с именем таблицы, с которой нужно произвести объединение. CROSS JOIN формирует таблицу перекрестным соединением (декартовым произведением) двух таблиц:

PHP
$users DB::table('sizes')
            ->
crossJoin('colours')
            ->
get();

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

Вы можете указать более сложные условия для объединения. Для начала передайте замыкание вторым аргументом метода PHPjoin(). Замыкание будет получать объект JoinClause, позволяя вам указать условия для объединения:

PHP
DB::table('users')
        ->
join('contacts', function ($join) {
            
$join->on('users.id''=''contacts.user_id')->orOn(...);
        })
        ->
get();

Если вы хотите использовать стиль «where» для ваших объединений, то можете использовать для этого методы PHPwhere() и PHPorWhere(). Вместо сравнения двух столбцов эти методы будут сравнивать столбец и значение:

PHP
DB::table('users')
        ->
join('contacts', function ($join) {
            
$join->on('users.id''=''contacts.user_id')
                 ->
where('contacts.user_id''>'5);
        })
        ->
get();

Слияние (UNION)

Конструктор запросов позволяет создавать слияния двух запросов вместе. Например, вы можете создать начальный запрос, а затем с помощью метода PHPunion() слить его со вторым запросом:

PHP
$first DB::table('users')
            ->
whereNull('first_name');

$users DB::table('users')
            ->
whereNull('last_name')
            ->
union($first)
            ->
get();

Также существует метод PHPunionAll() с аналогичными параметрами.

Условия WHERE

Простые условия WHERE

Для добавления в запрос условий where используйте метод PHPwhere() на экземпляре конструктора запросов. Самый простой вызов PHPwhere() требует три аргумента. Первый — имя столбца. Второй — оператор (любой из поддерживаемых базой данных). Третий — значение для сравнения со столбцом.

Например, вот запрос, проверяющий равенство значения столбца «votes» и 100:

PHP
$users DB::table('users')->where('votes''='100)->get();

Для удобства, если вам необходимо просто проверить равенство значения столбца и данного значения, вы можете передать значение сразу вторым аргументом метода PHPwhere():

PHP
$users DB::table('users')->where('votes'100)->get();

Разумеется, вы можете использовать различные другие операторы при написании условия where:

PHP
$users DB::table('users')
                ->
where('votes''>='100)
                ->
get();

$users DB::table('users')
                ->
where('votes''<>'100)
                ->
get();

$users DB::table('users')
                ->
where('name''like''T%')
                ->
get();
+ 5.2

добавлено в 5.2 ()

В функцию PHPwhere() также можно передать массив условий:

PHP
$users DB::table('users')->where([
  [
'status''=''1'],
  [
'subscribed''<>''1'],
])->
get();

Условия ИЛИ

Вы можете сцепить вместе условия where, а также условия or в запросе. Метод PHPorWhere() принимает те же аргументы, что и метод PHPwhere():

PHP
$users DB::table('users')
                    ->
where('votes''>'100)
                    ->
orWhere('name''John')
                    ->
get();

Дополнительные условия WHERE

В интервале

Метод PHPwhereBetween() проверяет, что значения столбца находится в указанном интервале:

PHP
$users DB::table('users')
                    ->
whereBetween('votes', [1100])->get();

Вне интервала

Метод PHPwhereNotBetween() проверяет, что значения столбца находится вне указанного интервала:

PHP
$users DB::table('users')
                    ->
whereNotBetween('votes', [1100])
                    ->
get();

Фильтрация по совпадению с массивом значений

Метод PHPwhereIn() проверяет, что значения столбца содержатся в данном массиве:

PHP
$users DB::table('users')
                    ->
whereIn('id', [123])
                    ->
get();

Метод PHPwhereNotIn() проверяет, что значения столбца не содержатся в данном массиве:

PHP
$users DB::table('users')
                    ->
whereNotIn('id', [123])
                    ->
get();

Поиск неустановленных значений (NULL)

Метод PHPwhereNull() проверяет, что значения столбца равны PHPNULL:

PHP
$users DB::table('users')
                    ->
whereNull('updated_at')
                    ->
get();

Метод PHPwhereNotNull() проверяет, что значения столбца не равны PHPNULL:

PHP
$users DB::table('users')
                    ->
whereNotNull('updated_at')
                    ->
get();
+ 5.0

добавлено в 5.0 ()

Динамические условия WHERE

Вы можете использовать даже «динамические» условия where для гибкого построения операторов, используя магические методы:

PHP
$admin DB::table('users')->whereId(1)->first();

$john DB::table('users')
                      ->
whereIdAndEmail(2'john@doe.com')
                      ->
first();

$jane DB::table('users')
                      ->
whereNameOrAge('Jane'22)
                      ->
first();
+ 5.2

добавлено в 5.2 ()

whereColumn

Для проверки на совпадение двух столбцов можно использовать метод PHPwhereColumn():

PHP
$users DB::table('users')
                ->
whereColumn('first_name''last_name');

В метод также можно передать оператор сравнения:

PHP
$users DB::table('users')
                ->
whereColumn('updated_at''>''created_at');

В метод PHPwhereColumn() также можно передать массив с несколькими условиями. Эти условия будут объединены оператором AND:

PHP
$users DB::table('users')
                ->
whereColumn([
                  [
'first_name''last_name'],
                  [
'updated_at''>''created_at']
                ]);

Сложная фильтрация (WHERE)

Группировка условий

Иногда вам нужно сделать выборку по более сложным параметрам, таким как «существует ли» или вложенная группировка условий. Конструктор запросов Laravel справится и с такими запросами. Для начала посмотрим на пример группировки условий в скобках:

PHP
DB::table('users')
            ->
where('name''=''John')
            ->
orWhere(function ($query) {
                
$query->where('votes''>'100)
                      ->
where('title''<>''Admin');
            })
            ->
get();

Как видите, передав замыкание в метод PHPorWhere(), мы дали конструктору запросов команду, начать группировку условий. Замыкание получит экземпляр конструктора запросов, который вы можете использовать для задания условий, поместив их в скобки. Приведённый пример выполнит такой SQL-запрос:

sqlselect * from users where name = 'John' or (votes > 100 and title <> 'Admin')

Проверка на существование

Метод PHPwhereExists() позволяет написать SQL-условие where exists. Метод PHPwhereExists() принимает в качестве аргумента замыкание, которое получит экземпляр конструктора запросов, позволяя вам определить запрос для помещения в условие «exists»:

PHP
DB::table('users')
            ->
whereExists(function ($query) {
                
$query->select(DB::raw(1))
                      ->
from('orders')
                      ->
whereRaw('orders.user_id = users.id');
            })
            ->
get();

Этот пример выполнит такой SQL-запрос:

sqlselect * from users
where exists (
  select 1 from orders where orders.user_id = users.id
)
+ 5.2

добавлено в 5.2 ()

JSON фильтрация (WHERE)

Laravel поддерживает запросы для столбцов типа JSON в тех БД, которые поддерживают тип столбцов JSON. На данный момент это MySQL 5.7 и Postgres. Для запроса JSON столбца используйте оператор -> :

PHP
$users DB::table('users')
                ->
where('options->language''en')
                ->
get();

$users DB::table('users')
                ->
where('preferences->dining->meal''salad')
                ->
get();

Упорядочивание, группировка, предел и смещение

orderBy

Метод PHPorderBy() позволяет вам отсортировать результат запроса по заданному столбцу. Первый аргумент метода PHPorderBy() — столбец для сортировки по нему, а второй — задаёт направление сортировки и может быть либо asc, либо desc:

PHP
$users DB::table('users')
                ->
orderBy('name''desc')
                ->
get();
+ 5.2

добавлено в 5.2 ()

inRandomOrder

Для сортировки результатов запроса в случайном порядке можно использовать метод PHPinRandomOrder(). Например, вы можете использовать этот метод для выбора случайного пользователя:

PHP
$randomUser DB::table('users')
                ->
inRandomOrder()
                ->
first();

groupBy / having / havingRaw

Методы PHPgroupBy() и PHPhaving() используются для группировки результатов запроса. Сигнатура метода PHPhaving() аналогична методу PHPwhere():

PHP
$users DB::table('users')
                ->
groupBy('account_id')
                ->
having('account_id''>'100)
                ->
get();

Метод PHPhavingRaw() используется для передачи сырой строки в условие having. Например, мы можем найти все филиалы с объёмом продаж выше $2,500:

PHP
$users DB::table('orders')
                ->
select('department'DB::raw('SUM(price) as total_sales'))
                ->
groupBy('department')
                ->
havingRaw('SUM(price) > 2500')
                ->
get();

skip / take

Для ограничения числа возвращаемых результатов из запроса или для пропуска заданного числа результатов в запросе (OFFSET) используются методы PHPskip() и PHPtake():

PHP
$users DB::table('users')->skip(10)->take(5)->get();
+ 5.2

добавлено в 5.2 ()

Условные операторы

Иногда необходимо применять оператор к запросу, только если выполняется какое-то другое условие. Например, выполнять оператор PHPwhere, только если нужное значение есть во входящем запросе. Это можно сделать с помощью метода PHPwhen():

PHP
$role $request->input('role');

$users DB::table('users')
                ->
when($role, function ($query) use ($role) {
                  return 
$query->where('role_id'$role);
                })
                ->
get();

Метод PHPwhen() выполняет данное замыкание, только когда первый параметр равен PHPtrue. Если первый параметр равен PHPfalse, то замыкание не будет выполнено.

Вставка (INSERT)

Конструктор запросов предоставляет метод PHPinsert() для вставки записей в таблицу БД. Метод PHPinsert() принимает массив имён столбцов и значения для вставки:

PHP
DB::table('users')->insert(
  [
'email' => 'john@example.com''votes' => 0]
);

Вы можете вставить в таблицу сразу несколько записей одним вызовом PHPinsert(), передав ему массив массивов, каждый из которых — строка для вставки в таблицу:

PHP
DB::table('users')->insert([
  [
'email' => 'taylor@example.com''votes' => 0],
  [
'email' => 'dayle@example.com''votes' => 0]
]);

Автоинкрементные ID

Если в таблице есть автоинкрементный ID, используйте метод PHPinsertGetId() для вставки записи и получения её ID:

PHP
$id DB::table('users')->insertGetId(
  [
'email' => 'john@example.com''votes' => 0]
);

При использовании метода PHPinsertGetId() для PostgreSQL автоинкрементное поле должно иметь имя PHPid. Если вы хотите получить ID из другого поля таблицы, вы можете передать его имя вторым аргументом.

Обновление (UPDATE)

Разумеется, кроме вставки записей в БД конструктор запросов может и изменять существующие строки с помощью метода PHPupdate(). Метод PHPupdate(), как и метод PHPinsert(), принимает массив столбцов и пар значений, содержащих столбцы для обновления. Вы можете ограничить запрос PHPupdate() условием PHPwhere():

PHP
DB::table('users')
            ->
where('id'1)
            ->
update(['votes' => 1]);

Increment / Decrement

Конструктор запросов предоставляет удобные методы для увеличения и уменьшения значений заданных столбцов. Это просто более выразительный и краткий способ по сравнению с написанием оператора update вручную.

Оба метода принимают один обязательный аргумент — столбец для изменения. Второй аргумент может быть передан для указания, на какую величину необходимо изменить значение столбца.

PHP
DB::table('users')->increment('votes');

DB::table('users')->increment('votes'5);

DB::table('users')->decrement('votes');

DB::table('users')->decrement('votes'5);

Вы также можете указать дополнительные поля для изменения:

PHP
DB::table('users')->increment('votes'1, ['name' => 'John']);

Удаление (DELETE)

Конструктор запросов предоставляет метод PHPdelete() для удаления записей из таблиц:

PHP
DB::table('users')->delete();

Вы можете ограничить оператор PHPdelete(), добавив условие PHPwhere() перед его вызовом:

PHP
DB::table('users')->where('votes''>'100)->delete();

Если вы хотите очистить таблицу (усечение), удалив все строки и обнулив счётчик ID, используйте метод PHPtruncate():

PHP
DB::table('users')->truncate();

Усечение таблицы аналогично удалению всех её записей, а также сбросом счётчика autoincrement-полей. — прим. пер.

Пессимистическая блокировка

В конструкторе запросов есть несколько функций, которые помогают делать «пессимистическую блокировку» (pessimistic locking) для ваших операторов SELECT. Для запуска оператора SELECT с «разделяемой блокировкой» вы можете использовать в запросе метод PHPsharedLock(). Разделяемая блокировка предотвращает изменение выбранных строк до конца транзакции:

PHP
DB::table('users')->where('votes''>'100)->sharedLock()->get();

Или вы можете использовать метод PHPlockForUpdate(). Блокировка «для изменения» предотвращает изменение строк и их выбор другими разделяемыми блокировками:

PHP
DB::table('users')->where('votes''>'100)->lockForUpdate()->get();

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.