{{TOC}} {{DOCVER 4.0=0da300f6445bec5a70d007f503834fce957b065b 16.10.2014 5:19:26, 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03, 4.2=d7b13440c003218ed79e9d508706eca01990122f 4.12.2014 5:01:15}} == Введение == Конструктор запросов предоставляет удобный, выразительный интерфейс для создания и выполнения запросов к базе данных. Он может использоваться для выполнения большинства типов операций и работает со всеми поддерживаемыми СУБД. .(alert) **Внимание:** конструктор запросов Laravel использует привязку параметров к запросам средствами PDO для защиты вашего приложения от SQL-инъекций. Нет необходимости экранировать строки перед их передачей в запрос. == Выборка (%%(t)SELECT%%) == **Получение всех записей таблицы** %% $users = DB::table('users')->get(); foreach ($users as $user) { var_dump($user->name); } %% **Получение одной записи** %% $user = DB::table('users')->where('name', 'Джон')->first(); var_dump($user->name); %% **Получение одного поля из записей** %% $name = DB::table('users')->where('name', 'Джон')->pluck('name'); %% **Получение списка всех значений одного поля** %% $roles = DB::table('roles')->lists('title'); %% Этот метод вернёт массив всех заголовков (//title//). Вы можете указать произвольный ключ для возвращаемого массива: %% $roles = DB::table('roles')->lists('title', 'name'); %% **Указание полей для выборки** %% $users = DB::table('users')->select('name', 'email')->get(); $users = DB::table('users')->distinct()->get(); $users = DB::table('users')->select('name as user_name')->get(); %% **Добавление полей к созданному запросу** %% $query = DB::table('users')->select('name'); $users = $query->addSelect('age')->get(); %% **Фильтрация через %%(t)WHERE%%** %% $users = DB::table('users')->where('votes', '>', 100)->get(); %% **Условия //ИЛИ//** %% $users = DB::table('users') ->where('votes', '>', 100) ->orWhere('name', 'Джон') ->get(); %% **Фильтрация по интервалу значений** %% $users = DB::table('users') ->whereBetween('votes', array(1, 100))->get(); %% %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) **Фильтрация по отсутствию в интервале** ~%% $users = DB::table('users') ->whereNotBetween('votes', array(1, 100))->get(); ~%% %% **Фильтрация по совпадению с массивом значений** %% $users = DB::table('users') ->whereIn('id', array(1, 2, 3))->get(); $users = DB::table('users') ->whereNotIn('id', array(1, 2, 3))->get(); %% **Поиск неустановленных значений (%%(t)NULL%%)** %% $users = DB::table('users') ->whereNull('updated_at')->get(); %% **Использование %%(t)ORDER BY%%, %%(t)GROUP BY%% и %%(t)HAVING%%** %% $users = DB::table('users') ->orderBy('name', 'desc') ->groupBy('count') ->having('count', '>', 100) ->get(); %% **Смещение от начала и лимит числа возвращаемых строк** %% $users = DB::table('users')->skip(10)->take(5)->get(); %% == Объединения (%%(t)JOIN%%) == Конструктор запросов может быть использован для выборки данных из нескольких таблиц через %%JOIN%%. Посмотрите на примеры ниже. **Простое объединение** %% DB::table('users') ->join('contacts', 'users.id', '=', 'contacts.user_id') ->join('orders', 'users.id', '=', 'orders.user_id') ->select('users.id', 'contacts.phone', 'orders.price'); ->get(); %% **Объединение типа %%(t)LEFT JOIN%%** %% DB::table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->get(); %% Вы можете указать более сложные условия: %% DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get(); %% %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) Если вы хотите использовать стиль "where" для ваших объединений, то можете использовать для этого методы %%where()%% и %%orWhere()%%. Вместо сравнения двух столбцов эти методы будут сравнивать столбец и значение: ~%% DB::table('users') ->join('contacts', function($join) { $join->on('users.id', '=', 'contacts.user_id') ->where('contacts.user_id', '>', 5); }) ->get(); ~%% %% == Сложная фильтрация (%%(t)WHERE%%) == **Группировка условий** Иногда вам нужно сделать выборку по более сложным параметрам, таким как "существует ли" или вложенная группировка условий. Конструктор запросов Laravel справится и с такими запросами: %% DB::table('users') ->where('name', '=', 'Джон') ->orWhere(function ($query) { $query->where('votes', '>', 100) ->where('title', '<>', 'Админ'); }) ->get(); %% Команда выше выполнит такой SQL: %%(sql) select * from users where name = 'Джон' or (votes > 100 and title <> 'Админ') %% **Проверка на существование** %% DB::table('users') ->whereExists(function ($query) { $query->select(DB::raw(1)) ->from('orders') ->whereRaw('orders.user_id = users.id'); }) ->get(); %% Эта команда выше выполнит такой запрос: %%(sql) select * from users where exists ( select 1 from orders where orders.user_id = users.id ) %% == Агрегатные функции == Конструктор запросов содержит множество агрегатных методов, таких как **count**, **max**, **min**, **avg** и **sum**. %% $users = DB::table('users')->count(); $price = DB::table('orders')->max('price'); $price = DB::table('orders')->min('price'); $price = DB::table('orders')->avg('price'); $total = DB::table('users')->sum('votes'); %% == Сырые выражения == Иногда вам может быть нужно использовать уже готовое SQL-выражение в вашем запросе. Такие выражения вставляются в запрос напрямую в виде строк, поэтому будьте внимательны и не создавайте возможных точек для SQL-инъекций. Для создания сырого выражения используется метод %%DB::raw()%%. **Использование сырого выражения** %% $users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get(); %% == Вставка (%%(t)INSERT%%) == **Вставка записи в таблицу** %% DB::table('users')->insert( array('email' => 'john@example.com', 'votes' => 0) ); %% **Вставка записи и получение её нового ID** Если таблица имеет автоматическое числовое поле (//autoincrementing//), то можно использовать метод %%insertGetId()%% для вставки записи и получения её порядкового номера: %% $id = DB::table('users')->insertGetId( array('email' => 'john@example.com', 'votes' => 0) ); %% .(alert) **Внимание:** при использовании PostgreSQL автоматическое поле должно иметь имя %%id%%. **Вставка нескольких записей одновременно** %% DB::table('users')->insert(array( array('email' => 'taylor@example.com', 'votes' => 0), array('email' => 'dayle@example.com', 'votes' => 0), )); %% == Обновление (%%(t)UPDATE%%) == **Обновление записей в таблице** %% DB::table('users') ->where('id', 1) ->update(array('votes' => 1)); %% **Увеличение или уменьшение значения поля** %% DB::table('users')->increment('votes'); DB::table('users')->increment('votes', 5); DB::table('users')->decrement('votes'); DB::table('users')->decrement('votes', 5) %% Вы также можете указать дополнительные поля для изменения: %% DB::table('users')->increment('votes', 1, array('name' => 'Джон')); %% == Удаление (%%(t)DELETE%%) == **Удаление записей из таблицы** %% DB::table('users')->where('votes', '<', 100)->delete(); %% **Удаление всех записей** %% DB::table('users')->delete(); %% **Усечение таблицы** %% DB::table('users')->truncate(); %% .(tl_note) Усечение таблицы аналогично удалению всех её записей, а также сбросом счётчика //autoincrement//-полей. - //прим. пер.// == Слияние (%%(t)UNION%%) == Конструктор запросов позволяет создавать слияния двух запросов вместе: %% $first = DB::table('users')->whereNull('first_name'); $users = DB::table('users')->whereNull('last_name')->union($first)->get(); %% Также существует метод %%unionAll()%% с аналогичными параметрами. %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) == Пессимистическая блокировка == В построителе запросов есть несколько функций, которые помогают делать "пессимистическую блокировку" для ваших операторов SELECT. Для запуска оператора SELECT с "разделяемой блокировкой" вы можете использовать в запросе метод %%sharedLock%%: ~%% DB::table('users')->where('votes', '>', 100)->sharedLock()->get(); ~%% Чтобы "блокировать обновление" для оператора SELECT, вы можете использовать в запросе метод %%lockForUpdate%%: ~%% DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get(); ~%% %% == Кэширование запросов == Вы можете легко закэшировать результат выполнения запроса методом %%remember()%%: %% $users = DB::table('users')->remember(10)->get(); %% В этом примере результаты выборки будут сохранены в кэше на 10 минут. В течении этого времени данный запрос не будет отправляться к СУБД - вместо этого результат будет получен из системы кэширования, указанной по умолчанию в вашем файле настроек. %%(DOCNEW 4.1=efd541a0b218b1c6aafb73f0051c18ed150e3c24 25.05.2014 6:21:03) Если вы используете ((/docs/v4/cache#теги поддерживаемый драйвер кэша)), то можете добавить в кэш теги: ~%% $users = DB::table('users')->cacheTags(array('people', 'authors'))->remember(10)->get(); ~%% %%