База Данных: Начало работы
Введение
Почти каждое современное веб-приложение взаимодействует с базой данных. Laravel делает взаимодействие с базами данных чрезвычайно простым в различных поддерживаемых базах данных, используя необработанный SQL, построитель запросов и Eloquent ORM. В настоящее время Laravel обеспечивает собственную поддержку пяти баз данных:
- MariaDB 10.2+ (Version Policy)
- MySQL 5.7+ (Version Policy)
- PostgreSQL 9.6+ (Version Policy)
- SQLite 3.8.8+
- SQL Server 2017+ (Version Policy)
Конфигурация
Конфигурация служб базы данных Laravel находится в файле конфигурации config/database.php
вашего приложения. В этом файле вы можете определить все ваши подключения к базе данных, а также указать, какое подключение должно использоваться по умолчанию. Большинство параметров конфигурации в этом файле управляются значениями переменных среды вашего приложения. В этом файле представлены примеры для большинства поддерживаемых Laravel систем баз данных.
По умолчанию образец Laravel конфигурация среды готов к использованию с Laravel Sail, который является Конфигурация Docker для разработки приложений Laravel на вашем локальном компьютере. Однако вы можете изменить конфигурацию базы данных по мере необходимости для вашей локальной базы данных.
Конфигурация SQLite
Базы данных SQLite содержатся в одном файле в вашей файловой системе. Вы можете создать новую базу данных SQLite, используя команду touch
в своем терминале: touch database/database.sqlite
. После создания базы данных вы можете легко настроить переменные среды, чтобы они указывали на эту базу данных, поместив абсолютный путь к базе данных в переменную среды DB_DATABASE
:
DB_CONNECTION=sqliteDB_DATABASE=/absolute/path/to/database.sqlite
Чтобы включить ограничения внешнего ключа для соединений SQLite, вы должны установить для переменной среды DB_FOREIGN_KEYS
значение true
:
DB_FOREIGN_KEYS=true
Конфигурация Microsoft SQL Server
Чтобы использовать базу данных Microsoft SQL Server, вы должны убедиться, что у вас установлены расширения PHP sqlsrv
и pdo_sqlsrv
, а также любые зависимости, которые могут потребоваться для них, такие как драйвер Microsoft SQL ODBC.
Конфигурация с использованием URL-адресов
Обычно подключения к базе данных настраиваются с использованием нескольких значений конфигурации, таких как host
, database
, username
, password
и т. д. Каждое из этих значений конфигурации имеет свою собственную соответствующую переменную среды. Это означает, что при настройке информации о подключении к базе данных на рабочем сервере вам необходимо управлять несколькими переменными среды.
Некоторые поставщики управляемых баз данных, такие как AWS и Heroku, предоставляют единую базу данных «URL», которая содержит всю информацию о подключении к базе данных в одной строке. Пример URL-адреса базы данных может выглядеть примерно так:
mysql://root:password@127.0.0.1/forge?charset=UTF-8
Эти URL-адреса обычно следуют стандартному соглашению о схеме:
driver://username:password@host:port/database?options
Для удобства Laravel поддерживает эти URL-адреса в качестве альтернативы настройке вашей базы данных с несколькими параметрами конфигурации. Если параметр конфигурации url
(или соответствующая переменная среды DATABASE_URL
) присутствует, он будет использоваться для извлечения информации о соединении с базой данных и учетных данных.
Чтение и запись соединений
Иногда вам может понадобиться использовать одно соединение с базой данных для операторов SELECT, а другое — для операторов INSERT, UPDATE и DELETE. Laravel упрощает эту задачу, и правильные соединения всегда будут использоваться независимо от того, используете ли вы необработанные запросы, query builder или Eloquent ORM.
Чтобы увидеть, как должны быть настроены соединения для чтения/записи, давайте посмотрим на этот пример:
'mysql' => [ 'read' => [ 'host' => [ '192.168.1.1', '196.168.1.2', ], ], 'write' => [ 'host' => [ '196.168.1.3', ], ], 'sticky' => true, 'driver' => 'mysql', 'database' => 'database', 'username' => 'root', 'password' => '', 'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci', 'prefix' => '',],
Обратите внимание, что в массив конфигурации добавлено три ключа: read
, write
и sticky
. Ключи read
и write
имеют значения массива, содержащие один ключ: host
. Остальные параметры базы данных для соединений read
и write
будут объединены из основного массива конфигурации mysql
.
Вам нужно только поместить элементы в массивы read
и write
, если вы хотите переопределить значения из основного массива mysql
. Таким образом, в этом случае 192.168.1.1
будет использоваться в качестве хоста для соединения "чтение", а 192.168.1.3
будет использоваться для соединения "записи". Учетные данные базы данных, префикс, набор символов и все другие параметры в основном массиве mysql
будут общими для обоих подключений. Когда в массиве конфигурации host
существует несколько значений, хост базы данных будет выбираться случайным образом для каждого запроса.
Опция sticky
Параметр sticky
является необязательным значением, которое можно использовать для немедленного чтения записей, которые были записаны в базу данных в течение текущего цикла запроса. Если опция sticky
включена и в течение текущего цикла запроса к базе данных была выполнена операция «записи», любые дальнейшие операции «чтения» будут использовать соединение «записи». Это гарантирует, что любые данные, записанные во время цикла запроса, могут быть немедленно считаны обратно из базы данных во время того же самого запроса. Вам решать, является ли это желаемым поведением для вашего приложения.
Запуск SQL-запросов
После того, как вы настроили соединение с базой данных, вы можете выполнять запросы, используя фасад DB
. Фасад DB
предоставляет методы для каждого типа запроса: select
, update
, insert
, delete
и statement
.
Выполнение запроса выбора
Чтобы выполнить базовый запрос SELECT, вы можете использовать метод select
на фасаде DB
:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller;use Illuminate\Support\Facades\DB; class UserController extends Controller{ /** * Show a list of all of the application's users. * * @return \Illuminate\Http\Response */ public function index() { $users = DB::select('select * from users where active = ?', [1]); return view('user.index', ['users' => $users]); }}
Первый аргумент, передаваемый методу select
— это SQL-запрос, а второй аргумент — любые привязки параметров, которые необходимо привязать к запросу. Как правило, это значения ограничений предложения where
. Привязка параметров обеспечивает защиту от SQL-инъекций.
Метод select
всегда будет возвращать массив array
результатов. Каждый результат в массиве будет PHP-объектом stdClass
, представляющим запись из базы данных:
use Illuminate\Support\Facades\DB; $users = DB::select('select * from users'); foreach ($users as $user) { echo $user->name;}
Использование именованных привязок
Вместо использования ?
для представления ваших привязок параметров вы можете выполнить запрос, используя именованные привязки:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
Запуск оператора вставки
Чтобы выполнить оператор insert
, вы можете использовать метод insert
на фасаде DB
. Подобно select
, этот метод принимает SQL-запрос в качестве первого аргумента и привязки в качестве второго аргумента:
use Illuminate\Support\Facades\DB; DB::insert('insert into users (id, name) values (?, ?)', [1, 'Marc']);
Запуск оператора обновления
Метод update
следует использовать для обновления существующих записей в базе данных. Метод возвращает количество строк, затронутых оператором:
use Illuminate\Support\Facades\DB; $affected = DB::update( 'update users set votes = 100 where name = ?', ['Anita']);
Запуск оператора Delete
Для удаления записей из базы данных следует использовать метод delete
. Как и в случае с update
, метод вернет количество затронутых строк:
use Illuminate\Support\Facades\DB; $deleted = DB::delete('delete from users');
Выполнение общего заявления
Некоторые операторы базы данных не возвращают никакого значения. Для этих типов операций вы можете использовать метод statement
на фасаде DB
:
DB::statement('drop table users');
Запуск неподготовленного оператора
Иногда вам может понадобиться выполнить оператор SQL без привязки каких-либо значений. Для этого вы можете использовать неподготовленный метод unprepared
фасада DB
:
DB::unprepared('update users set votes = 100 where name = "Dries"');
Поскольку неподготовленные операторы не связывают параметры, они могут быть уязвимы для SQL-инъекций. Вы никогда не должны разрешать значения, контролируемые пользователем, в неподготовленном операторе.
Неявные коммиты
При использовании методов statement
и unprepared
фасада DB
в транзакциях вы должны быть осторожны, чтобы избежать операторов, которые вызывают неявные фиксации. Эти операторы заставят механизм базы данных косвенно зафиксировать всю транзакцию, оставив Laravel в неведении об уровне транзакции базы данных. Примером такого оператора является создание таблицы базы данных:
DB::unprepared('create table a (col varchar(1) null)');
Пожалуйста, обратитесь к руководству MySQL для списка всех операторов, которые вызывают неявные фиксации.
Использование подключений к нескольким базам данных
Если ваше приложение определяет несколько соединений в файле конфигурации config/database.php
, вы можете получить доступ к каждому соединению с помощью метода connection
, предоставляемого фасадом DB
. Имя соединения, переданное методу connection
, должно соответствовать одному из соединений, перечисленных в вашем файле конфигурации config/database.php
или настроенных во время выполнения с помощью помощника config
:
use Illuminate\Support\Facades\DB; $users = DB::connection('sqlite')->select(...);
Вы можете получить доступ к необработанному базовому экземпляру PDO соединения, используя метод getPdo
для экземпляра соединения:
$pdo = DB::connection()->getPdo();
Прослушивание событий запроса
Если вы хотите указать замыкание, которое вызывается для каждого SQL-запроса, выполняемого вашим приложением, вы можете использовать метод listen
фасада DB
. Этот метод может быть полезен для регистрации запросов или отладки. Вы можете зарегистрировать замыкание прослушивателя запросов в методе boot
сервис провайдера:
<?php namespace App\Providers; use Illuminate\Support\Facades\DB;use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider{ /** * Register any application services. * * @return void */ public function register() { // } /** * Bootstrap any application services. * * @return void */ public function boot() { DB::listen(function ($query) { // $query->sql; // $query->bindings; // $query->time; }); }}
Транзакции базы данных
Вы можете использовать метод transaction
, предоставляемый фасадом DB
, для запуска набора операций в транзакции базы данных. Если при закрытии транзакции создается исключение, транзакция автоматически откатывается, и исключение создается повторно. Если закрытие выполняется успешно, транзакция будет автоматически зафиксирована. Вам не нужно беспокоиться о ручном откате или фиксации при использовании метода transaction
:
use Illuminate\Support\Facades\DB; DB::transaction(function () { DB::update('update users set votes = 1'); DB::delete('delete from posts');});
Обработка взаимоблокировок
Метод transaction
принимает необязательный второй аргумент, который определяет, сколько раз транзакция должна быть повторена при возникновении взаимоблокировки. Как только эти попытки будут исчерпаны, будет выдано исключение:
use Illuminate\Support\Facades\DB; DB::transaction(function () { DB::update('update users set votes = 1'); DB::delete('delete from posts');}, 5);
Ручное использование транзакций
Если вы хотите начать транзакцию вручную и иметь полный контроль над откатами и фиксациями, вы можете использовать метод beginTransaction
, предоставляемый фасадом DB
:
use Illuminate\Support\Facades\DB; DB::beginTransaction();
Вы можете откатить транзакцию с помощью метода rollBack
:
DB::rollBack();
Наконец, вы можете зафиксировать транзакцию с помощью метода commit
:
DB::commit();
Методы транзакций фасада
DB
управляют транзакциями как для query builder и Eloquent ORM.
Подключение к CLI базы данных
Если вы хотите подключиться к CLI вашей базы данных, вы можете использовать Artisan-команду db
:
php artisan db
При необходимости вы можете указать имя соединения с базой данных для соединения с соединением с базой данных, которое не является соединением по умолчанию:
php artisan db mysql