{{TOC}} {{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01, 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11}} == Введение == В Laravel можно чрезвычайно просто взаимодействовать с БД на различных "движках", будь то сырой SQL, ((/docs/v5/queries гибкий построитель запросов)) или ((/docs/v5/eloquent Eloquent ORM)). На данный момент Laravel поддерживает четыре системы баз данных: * MySQL * Postgres * SQLite * SQL Server === Настройка === Настройки работы с БД хранятся в файле %%(t)config/database.php%%. Здесь вы можете указать все используемые вами соединения к БД, а также задать соединение по умолчанию. Примеры настройки большинства поддерживаемых видов подключений находятся в этом же файле. По умолчанию образец ((//docs/v5/configuration#среда настройки окружения)) Laravel подготовлен для использования с ((//docs/v5/homestead Laravel Homestead)) - удобной виртуальной машиной для Laravel-разработки на вашей локальной машине. Разумеется, вы можете изменить эти настройки для работы с вашей локальной БД. %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15) **Настройка SQLite** После создания новой базы данных SQLite при помощи команды %%(sh)touch database/database.sqlite%%, вы можете легко настроить переменные вашей среды для этой новой базы данных, используя её абсолютный путь: %%(conf) DB_CONNECTION=sqlite DB_DATABASE=/absolute/path/to/database.sqlite ~%% **Настройка SQL Server** Laravel поддерживает работу с SQL Server из коробки, надо лишь добавить настройку подключения к БД в ваш файл настроек %%(t)config/database.php%%: %%(conf) 'sqlsrv' => [ 'driver' => 'sqlsrv', 'host' => env('DB_HOST', 'localhost'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), 'charset' => 'utf8', 'prefix' => '', ], ~%% %% ((#чтениезапись)) === Соединения для чтения и записи === Иногда вам может понадобиться использовать разные подключения к базе данных: одно для запросов %%(t)SELECT%%, а другое для запросов %%(t)INSERT%%, %%(t)UPDATE%% и %%(t)DELETE%%. В Laravel это делается очень просто, и всегда будет использоваться соответствующее соединение, используете ли вы сырые запросы, построитель запросов или Eloquent ORM. Чтобы увидеть, как должны быть настроены соединения чтения/записи, давайте посмотрим на этот пример: %% 'mysql' => [ 'read' => [ 'host' => '192.168.1.1', ], 'write' => [ 'host' => '196.168.1.2' ], 'driver' => 'mysql', 'database' => 'database', 'username' => 'root', 'password' => '', 'charset' => 'utf8', 'collation' => 'utf8_unicode_ci', 'prefix' => '', ], %% Обратите внимание, что в массив настроек были добавлены два элемента: %%(sql)'read'%% и %%(sql)'write'%%. Оба элемента представляют собой массив с одним элементом %%(sql)'host'%%. Остальные параметры БД для подключений чтения/записи будут заимствованы из основного массива %%(sql)'mysql'%%. Вам стоит размещать элементы в массивах %%read%% и %%write%%, только если вы хотите переопределить их значения из основного массива. Таким образом, в этом случае, //192.168.1.1// будет использоваться как хост для подключения "чтения", а //192.168.1.2// - для подключения "записи". Учётные данные для БД, префикс, набор символов, и все другие параметры основного массива %%(sql)'mysql'%% будут использованы для обоих подключений. == Использование нескольких соединений с БД == При использовании нескольких соединений с БД вы можете получить доступ к каждому из них через метод %%connection()%% фасада %%(t)DB%%. Передаваемое в этот метод имя %%(t)name%% должно соответствовать одному из перечисленных в файле %%(t)config/database.php%% соединений: %% $users = DB::connection('foo')->select(...); %% Вы также можете получить низкоуровневый объект ((phpdoc:book.pdo PDO)) для этого подключения методом %%getPdo()%%: %% $pdo = DB::connection()->getPdo(); %% == Выполнение сырых SQL-запросов == Когда вы настроили соединение с базой данных, вы можете выполнять запросы, используя фасад %%(t)DB%%. Этот фасад имеет методы для каждого типа запроса: %%(t)select%%, %%(t)update%%, %%(t)insert%%, %%(t)delete%% и %%(t)statement%%. **Выполнение запроса %%(t)SELECT%%** Чтобы выполнить базовый запрос, можно использовать метод %%select()%% фасада %%(t)DB%%: %% $users]); } } %% Первый аргумент метода %%select()%% - сырой SQL-запрос, второй - любые связки параметров для прикрепления к запросу. Обычно это значения ограничений условия %%(t)where%%. Привязка параметров обеспечивает защиту от SQL-инъекций. Метод %%select()%% всегда возвращает массив результатов. Каждый результат в массиве - объект PHP %%(t)StdClass%%, что позволяет вам обращаться к значениям результатов: %% foreach ($users as $user) { echo $user->name; } %% **Использование привязки имён** Вместо использования знака вопроса %%(t)?%% для обозначения привязки параметров, вы можете выполнить запрос, используя привязку по имени: %% $results = DB::select('select * from users where id = :id', ['id' => 1]); %% **Выполнение запроса %%(t)INSERT%%** Чтобы выполнить запрос %%(t)insert%%, можно использовать метод %%insert()%% фасада %%(t)DB%%. Как и %%select()%%, данный метод принимает сырой SQL-запрос первым аргументом, а вторым - привязки: %% DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']); %% **Выполнение запроса %%(t)UPDATE%%** Для обновления существующих записей в БД используется метод %%update()%%, который возвращает количество изменённых записей: %% $affected = DB::update('update users set votes = 100 where name = ?', ['John']); %% **Выполнение запроса %%(t)DELETE%%** Для удаления записей из БД используется метод %%delete()%%, который возвращает количество изменённых записей: %% $deleted = DB::delete('delete from users'); %% **Выполнение запроса общего типа** Некоторые запросы к БД не возвращают никаких значений. Для операций такого типа можно использовать метод %%statement()%% фасада %%(t)DB%%: %% DB::statement('drop table users'); %% === Прослушивание событий запросов === Если вы хотите получать каждый выполненный вашим приложением SQL-запрос, используйте метод %%listen()%%. Этот метод полезен для журналирования запросов и отладки. Вы можете зарегистрировать свой слушатель запросов в ((/docs/v5/providers сервис-провайдере)): %% sql // $query->bindings // $query->time //В этом примере из документации по версии 5.1 и ранее было: //DB::listen(function($sql, $bindings, $time) { // // }); } /** * Регистрация сервис-провайдера. * * @return void */ public function register() { // } } %% == Транзакции == Для выполнения набора запросов внутри одной транзакции вы можете использовать метод %%transaction()%% фасада %%(t)DB%%. Если в замыкании транзакции произойдёт исключение, она автоматически откатится. А если замыкание выполнится успешно, транзакция автоматически применится к БД. Вам не стоит переживать об этом при использовании метода %%transaction()%%: %% DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); }); %% %%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51) **Обработка взаимных блокировок** Метод %%transaction()%% принимает второй необязательный аргумент, с помощью которого задаётся число повторных попыток транзакции при возникновении взаимной блокировки (англ. deadlock). После истечения этих попыток будет выброшено исключение: ~%% DB::transaction(function () { DB::table('users')->update(['votes' => 1]); DB::table('posts')->delete(); }, 5); ~%% %% **Ручное использование транзакций** Если вы хотите запустить транзакцию вручную и иметь полный контроль над её откатом и применением, используйте метод %%beginTransaction()%% фасада %%(t)DB%%: %% DB::beginTransaction(); %% Вы можете откатить транзакцию методом %%rollback()%%: %% DB::rollback(); %% Наконец, вы можете применить транзакцию методом %%commit()%%: %% DB::commit(); %% .(alert) Методы фасада %%(t)DB%% для транзакций также контролируют транзакции ((/docs/v5/queries построителя запросов)) и ((/docs/v5/eloquent Eloquent ORM)). .(tl_note) **Транзакция** - особое состояние БД, в котором выполняемые запросы либо все вместе успешно завершаются, либо (в случае ошибки) все их изменения откатываются. Это позволяет поддерживать целостность внутренней структуры данных. К примеру, если вы вставляете запись о заказе, а затем в отдельную таблицу добавляете товары, то при неуспешном выполнении скрипта (в том числе падения веб-сервера, ошибки в запросе и пр.) СУБД автоматически удалит запись о заказе и все товары, которые вы успели добавить - //прим. пер.// %%(DOCNEW 5.0=5d10040a981deee82c0fde0e8e5d2ffc49eaaecb 8.02.2016 18:09:11) Иногда вам может понадобиться переподключиться и вы можете сделать это так: ~%% DB::reconnect('foo'); ~%% Если вам нужно отключиться от данной БД из-за превышения основного предела экземпляров PDO //max_connections//, используйте метод %%disconnect()%%: ~%% DB::disconnect('foo'); ~%% == Журнал запросов == По умолчанию Laravel записывает все SQL-запросы, выполненные в рамках текущего запроса страницы. Однако в некоторых случаях - например, при вставке большого набора записей - это может быть слишком ресурсозатратно. Для подключения журнала вы можете использовать метод %%enableQueryLog()%%: ~%% DB::connection()->enableQueryLog(); ~%% Чтобы получить массив выполненных запросов, вы можете использовать метод %%getQueryLog()%%: ~%% $queries = DB::getQueryLog(); ~%% %%