База данных: основы
Введение
Laravel делает работу с БД чрезвычайно простой благодаря возможности работы на трех уровнях: на чистом SQL, через конструктор запросов fluent query builder, через объектные модели Eloquent ORM. Laravel поддерживает четыре СУБД:
- MySQL
- Postgres
- SQLite
- SQL Server
Настройка
Файл настройки БД находится в config/database.php
. В нем можно опеределить все подключения к БД, задать подключение по умолчанию. Также в файле есть примеры для всех СУБД. Конфигурация по умолчанию готова для работы с виртуальной машиной Laravel Homestead, которая удобна для разработки на локальной машине. Конечно, вы можете менять конфигурацию в файле под ваши нужды.
Настройка SQL Server
SQL Server Configuration
Laravel поддерживает SQL Server "из коробки", однако, в файл настройки требуется добавить параметры подключения:
'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, and DELETE), то Laravel позваоляет это сделать на одном дыхании. Соответствующее подключение будет автоматически использоваться при работе с БД любым из способов: чистый SQL, конструктор запросов, объектные модели (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' => '',
],
Обратите внимание, что в массив настройки были добавлены два ключа: read
and write
. Каждый из них является массивом, в котором содержится единственный ключ: host
. Остальные опции подключений являются общими и заданы непосредственно в массиве mysql
.
Таким образом, нам нужно будет добавлять параметры в массивы read
и write
, только, если мы хотим переписать значения этих параметров в основном массиве. Так в приведенном примере хост 192.168.1.1
будет использоваться для чтения, а 192.168.1.2
для записи. Учетные данные, префикс, кодировка и все другие опции в массиве mysql
будут общими для обоих подключений.
Запросы на чистом SQL
После настройки подключения к БД вы можете делать запросы, используя фасад DB
. Фасад предоставляет методы для каждого типа запроса: select
, update
, insert
, delete
, и statement
.
SQL запросы
Для простого запроса мы можем использовать метод select
фасада DB
:
<?php
namespace App\Http\Controllers;
use DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* Show a list of all of the application's users.
*
* @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
фасада DB
. Использование метода подобно методу select
, где первый аргумент - запрос на SQL, второй - параметры:
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
Обновление
Метод update
используется для обновления записей в БД. Возвращает количество обновленных строк:
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);
Удаление
Метод delete
используется для удаления записей из таблицы. Возвращает количество удаленных строк:
$deleted = DB::delete('delete from users');
Иные запросы к БД
Используйте метод statement
фасада DB
:
DB::statement('drop table users');
Постобработчик запросов
Если вы хотите получать каждый SQL запрос, выполненый приложением, используйте метод listen
. Этот метод полезен для
логирования и отладки запросов. Регистрация постобработчика в service provider:
<?php
namespace App\Providers;
use DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
DB::listen(function($query) {
// $query->sql
// $query->bindings
// $query->time
});
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
Транзакции
Для использования транзакций предназначен метод transaction
фасада DB
. Если будет брошено исключение в функции-замыкании, то транзакция будет отменена. Если транзакция успешна, то она будет автоматически завершена(committed). Вам не требуется вручную делать откат или завершение (committing) при использовании этого метода:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
Ручные транзакции
Если требуется начать транзакцию вручную и иметь полный контроль над откатами и завершениями используйте метод beginTransaction
фасада DB
:
DB::beginTransaction();
Откат транзакции:
DB::rollBack();
Завершение транзакции:
DB::commit();
Примечание: Используйте перечисленные методы для ручного управления транзакциями при работе с query builder и Eloquent ORM.
Использование нескольких подключений к БД
При использовании нескольких подключений доступ к каждому из них можно получить через метод connection
. Методу необходимо передать имя подключения, которое должно соответствовать одному из имен в файле настройки БД config/database.php
:
$users = DB::connection('foo')->select(...);
Вы также можете получить низкоуровневый объект PDO для текущего подключения:
$pdo = DB::connection()->getPdo();