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

Основы работы с базами данных

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

  1. 1. Введение
    1. 1.1. Настройка
    2. 1.2. Соединения для чтения и записи
  2. 2. Использование нескольких соединений с БД
  3. 3. Выполнение сырых SQL-запросов
    1. 3.1. Прослушивание событий запросов
  4. 4. Транзакции
  5. 5. Журнал запросов
Этот перевод актуален для англоязычной документации на (ветка 5.3) , (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

В Laravel можно чрезвычайно просто взаимодействовать с БД на различных «движках», будь то сырой SQL, гибкий построитель запросов или Eloquent ORM. На данный момент Laravel поддерживает четыре системы баз данных:

  • MySQL
  • Postgres
  • SQLite
  • SQL Server

Настройка

Настройки работы с БД хранятся в файле config/database.php. Здесь вы можете указать все используемые вами соединения к БД, а также задать соединение по умолчанию. Примеры настройки большинства поддерживаемых видов подключений находятся в этом же файле.

По умолчанию образец настройки окружения Laravel подготовлен для использования с Laravel Homestead — удобной виртуальной машиной для Laravel-разработки на вашей локальной машине. Разумеется, вы можете изменить эти настройки для работы с вашей локальной БД.

+ 5.3 5.2

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

Настройка SQLite

После создания новой базы данных SQLite при помощи команды shtouch database/database.sqlite, вы можете легко настроить переменные вашей среды для этой новой базы данных, используя её абсолютный путь:

confDB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite

Настройка SQL Server

Laravel поддерживает работу с SQL Server из коробки, надо лишь добавить настройку подключения к БД в ваш файл настроек 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' => '',
],

Соединения для чтения и записи

Иногда вам может понадобиться использовать разные подключения к базе данных: одно для запросов SELECT, а другое для запросов INSERT, UPDATE и DELETE. В Laravel это делается очень просто, и всегда будет использоваться соответствующее соединение, используете ли вы сырые запросы, построитель запросов или Eloquent ORM.

Чтобы увидеть, как должны быть настроены соединения чтения/записи, давайте посмотрим на этот пример:

PHP
'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'.

Вам стоит размещать элементы в массивах PHPread и PHPwrite, только если вы хотите переопределить их значения из основного массива. Таким образом, в этом случае, 192.168.1.1 будет использоваться как хост для подключения «чтения», а 192.168.1.2 — для подключения «записи». Учётные данные для БД, префикс, набор символов, и все другие параметры основного массива sql'mysql' будут использованы для обоих подключений.

Использование нескольких соединений с БД

При использовании нескольких соединений с БД вы можете получить доступ к каждому из них через метод PHPconnection() фасада DB. Передаваемое в этот метод имя name должно соответствовать одному из перечисленных в файле config/database.php соединений:

PHP
$users DB::connection('foo')->select(...);

Вы также можете получить низкоуровневый объект PDO для этого подключения методом PHPgetPdo():

PHP
$pdo DB::connection()->getPdo();

Выполнение сырых SQL-запросов

Когда вы настроили соединение с базой данных, вы можете выполнять запросы, используя фасад DB. Этот фасад имеет методы для каждого типа запроса: select, update, insert, delete и statement.

Выполнение запроса SELECT

Чтобы выполнить базовый запрос, можно использовать метод PHPselect() фасада DB:

PHP
<?php

namespace App\Http\Controllers;

use 
Illuminate\Support\Facades\DB;
//для версии 5.2 и ранее:
//use 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]);
  }
}

Первый аргумент метода PHPselect() — сырой SQL-запрос, второй — любые связки параметров для прикрепления к запросу. Обычно это значения ограничений условия where. Привязка параметров обеспечивает защиту от SQL-инъекций.

Метод PHPselect() всегда возвращает массив результатов. Каждый результат в массиве — объект PHP StdClass, что позволяет вам обращаться к значениям результатов:

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

Использование привязки имён

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

PHP
$results DB::select('select * from users where id = :id', ['id' => 1]);

Выполнение запроса INSERT

Чтобы выполнить запрос insert, можно использовать метод PHPinsert() фасада DB. Как и PHPselect(), данный метод принимает сырой SQL-запрос первым аргументом, а вторым — привязки:

PHP
DB::insert('insert into users (id, name) values (?, ?)', [1'Dayle']);

Выполнение запроса UPDATE

Для обновления существующих записей в БД используется метод PHPupdate(), который возвращает количество изменённых записей:

PHP
$affected DB::update('update users set votes = 100 where name = ?', ['John']);

Выполнение запроса DELETE

Для удаления записей из БД используется метод PHPdelete(), который возвращает количество изменённых записей:

PHP
$deleted DB::delete('delete from users');

Выполнение запроса общего типа

Некоторые запросы к БД не возвращают никаких значений. Для операций такого типа можно использовать метод PHPstatement() фасада DB:

PHP
DB::statement('drop table users');

Прослушивание событий запросов

Если вы хотите получать каждый выполненный вашим приложением SQL-запрос, используйте метод PHPlisten(). Этот метод полезен для журналирования запросов и отладки. Вы можете зарегистрировать свой слушатель запросов в сервис-провайдере:

PHP
<?php

namespace App\Providers;

use 
Illuminate\Support\Facades\DB;
//для версии 5.2 и ранее:
//use DB;
use Illuminate\Support\ServiceProvider;

class 
AppServiceProvider extends ServiceProvider
{
  
/**
   * Загрузка всех сервисов приложения.
   *
   * @return void
   */
  
public function boot()
  {
    
DB::listen(function ($query) {
      
// $query->sql
      // $query->bindings
      // $query->time

    //В этом примере из документации по версии 5.1 и ранее было:
    //DB::listen(function($sql, $bindings, $time) {
    //  //

    
});
  }

  
/**
   * Регистрация сервис-провайдера.
   *
   * @return void
   */
  
public function register()
  {
    
//
  
}
}

Транзакции

Для выполнения набора запросов внутри одной транзакции вы можете использовать метод PHPtransaction() фасада DB. Если в замыкании транзакции произойдёт исключение, она автоматически откатится. А если замыкание выполнится успешно, транзакция автоматически применится к БД. Вам не стоит переживать об этом при использовании метода PHPtransaction():

PHP
DB::transaction(function () {
  
DB::table('users')->update(['votes' => 1]);

  
DB::table('posts')->delete();
});
+ 5.3

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

Обработка взаимных блокировок

Метод PHPtransaction() принимает второй необязательный аргумент, с помощью которого задаётся число повторных попыток транзакции при возникновении взаимной блокировки (англ. deadlock). После истечения этих попыток будет выброшено исключение:

PHP
DB::transaction(function () {
  
DB::table('users')->update(['votes' => 1]);

  
DB::table('posts')->delete();
}, 
5);

Ручное использование транзакций

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

PHP
DB::beginTransaction();

Вы можете откатить транзакцию методом PHProllback():

PHP
DB::rollback();

Наконец, вы можете применить транзакцию методом PHPcommit():

PHP
DB::commit();

Методы фасада DB для транзакций также контролируют транзакции построителя запросов и Eloquent ORM.

Транзакция — особое состояние БД, в котором выполняемые запросы либо все вместе успешно завершаются, либо (в случае ошибки) все их изменения откатываются. Это позволяет поддерживать целостность внутренней структуры данных. К примеру, если вы вставляете запись о заказе, а затем в отдельную таблицу добавляете товары, то при неуспешном выполнении скрипта (в том числе падения веб-сервера, ошибки в запросе и пр.) СУБД автоматически удалит запись о заказе и все товары, которые вы успели добавить — прим. пер.

+ 5.0

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

Иногда вам может понадобиться переподключиться и вы можете сделать это так:

PHP
DB::reconnect('foo');

Если вам нужно отключиться от данной БД из-за превышения основного предела экземпляров PDO max_connections, используйте метод PHPdisconnect():

PHP
DB::disconnect('foo');

Журнал запросов

По умолчанию Laravel записывает все SQL-запросы, выполненные в рамках текущего запроса страницы. Однако в некоторых случаях — например, при вставке большого набора записей — это может быть слишком ресурсозатратно. Для подключения журнала вы можете использовать метод PHPenableQueryLog():

PHP
DB::connection()->enableQueryLog();

Чтобы получить массив выполненных запросов, вы можете использовать метод PHPgetQueryLog():

PHP
$queries DB::getQueryLog();

Комментарии (2)

Max_G

Файла app/config/database.php не существует, но есть config/database.php

VikingBO

Жаль что так никто и не ответил за 5 лет человеку.
Аббревиатура app стандартно означает весь путь до папки приложения, поэтому вместо app принято подставлять например /var/www/html и в этом случае указание файла конфигурации вполне себе уместно. Единственно что для обозначения что это аббревиатура чаще всего пишут @app

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

Разметка: ? ?

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