Основы работы с базами данных
11.x
.
Почему это важно?
Введение
В Laravel можно чрезвычайно просто взаимодействовать с БД на различных “движках”, будь то сырой SQL, гибкий построитель запросов или Eloquent ORM. На данный момент Laravel поддерживает четыре системы баз данных:
Настройка
Настройка базы данных для вашего приложения хранится в config/database.php
. Здесь вы можете указать все используемые вами соединения к БД, а также задать соединение по умолчанию. Примеры настройки большинства поддерживаемых систем БД находятся в этом же файле.
По умолчанию образец настройки среды Laravel уже готов к использованию с Laravel Homestead — удобной виртуальной машиной для Laravel-разработки на вашей локальной машине. Разумеется, вы можете изменить эти настройки для работы с вашей локальной БД.
Настройка SQLite
После создания новой базы данных SQLite при помощи команды touch database/database.sqlite
, вы можете легко настроить переменные вашей среды для этой новой базы данных, используя её абсолютный путь:
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
Настройка SQL Server
Laravel изначально поддерживает работу с SQL Server; однако, потребуется добавить настройку подключения к БД в конфиге config/database.php
:
'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' => '',
],
Соединения для чтения и записи
Иногда вам может понадобиться использовать разные подключения к базе данных: одно для запросов SELECT, а другое для запросов INSERT, UPDATE и DELETE. это делается очень просто, и всегда будет использоваться соответствующее соединение, неважно используете ли вы сырые запросы, построитель запросов или Eloquent ORM.
Чтобы увидеть, как должны быть настроены соединения чтения/записи, давайте взглянем на этот пример:
'mysql' => [
'read' => [
'host' => '192.168.1.1',
],
'write' => [
'host' => '196.168.1.2'
],
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
Обратите внимание, что в массив настроек были добавлены два элемента: read
и write
. Оба элемента представляют собой массив с одним элементом: host
. Остальные параметры БД для подключений чтения/записи будут заимствованы из основного массива mysql
.
Вам стоит размещать элементы в массивах read
и write
aтолько если вы хотите переопределить их значения из основного массива. Таким образом, в этом случае, 192.168.1.1
будет использоваться как хост для подключения “чтения”, а 192.168.1.2
– для подключения “записи”. Учётные данные для БД, префикс, набор символов, и все другие параметры основного массива mysql
будут использованы для обоих подключений.
Использование нескольких соединений с БД
При использовании нескольких соединений с БД вы можете получить доступ к каждому из них через метод connection
фасада DB
. Передаваемое в этот метод имя name
должно соответствовать одному из перечисленных в файле config/database.php
:
$users = DB::connection('foo')->select(...);
Вы также можете получить низкоуровневый объект PDO для этого подключения методом getPdo
на экземпляре подключения:
$pdo = DB::connection()->getPdo();
Выполнение сырых SQL-запросов
После того как вы настроили соединение с базой данных, вы можете выполнять запросы, используя фасад DB
. Этот фасад имеет методы для каждого типа запроса: select
, update
, insert
, delete
и statement
.
Выполнение запроса Select
Чтобы выполнить базовый запрос, можно использовать метод select
фасада DB
:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Показать список всех пользователей приложения.
*
* @return Response
*/
public function index()
{
$users = DB::select('select * from users where active = ?', [1]);
return view('user.index', ['users' => $users]);
}
}
Первый аргумент метода select
— сырой SQL-запрос, второй — любые связки параметров для прикрепления к запросу. Обычно это значения ограничений условия where
. Привязка параметров обеспечивает защиту от SQL-внедрений.
Метод select
всегда возвращает массив результатов. Каждый результат в массиве будет объектом PHP stdClass
, что позволяет вам обращаться к значениям результатов:
foreach ($users as $user) {
echo $user->name;
}
Использование привязки имён
Вместо использования знака вопроса ?
для обозначения привязки параметров, вы можете выполнить запрос, используя привязку по имени:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
Выполнение запроса Insert
Чтобы выполнить запрос insert
, можно использовать метод insert
фасада DB
. Как и select
, данный метод принимает сырой SQL-запрос первым аргументом, а вторым — привязкиt:
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
Выполнение запроса Update
Для обновления существующих записей в БД используется метод update
, который возвращает количество изменённых записей:
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
Выполнение запроса Delete
Для удаления записей из БД используется метод delete
, который возвращает количество изменённых записей:
$deleted = DB::delete('delete from users');
Выполнение запроса общего типа
Некоторые запросы к БД не возвращают никаких значений. Для операций такого типа можно использовать метод statement
фасада DB
:
DB::statement('drop table users');
Прослушивание событий запросов
Если вы хотите получать каждый выполненный вашим приложением SQL-запрос, используйте метод listen
. Этот метод полезен для логгирования запросов и отладки. Вы можете зарегистрировать свой слушатель запросов в сервис-провайдере:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Загрузка всех сервисов приложения.
*
* @return void
*/
public function boot()
{
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
}
/**
* Регистрация сервис-провайдера.
*
* @return void
*/
public function register()
{
//
}
}
Транзакции БД
Для выполнения набора запросов внутри одной транзакции вы можете использовать метод transaction
фасада DB
. Если в функции-замыкании произойдёт исключение, транзакция автоматически откатится. А если функция выполнится успешно, транзакция автоматически применится к БД:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
Обработка взаимных блокировок
Метод transaction
принимает второй необязательный аргумент, с помощью которого задаётся число повторных попыток транзакции при возникновении взаимной блокировки. После истечения этих попыток будет выброшено исключение:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
}, 5);
Ручное использование транзакций
Если вы хотите запустить транзакцию вручную и иметь полный контроль над её откатом и применением, используйте метод beginTransaction
фасада DB
:
DB::beginTransaction();
Вы можете откатить транзакцию методом rollBack
:
DB::rollBack();
Наконец, вы можете применить транзакцию методом commit
:
DB::commit();
Методы фасада
DB
для транзакций также контролируют транзакции построителя запросов и Eloquent ORM.