Базы данных. Введение.

Содержание:


Введение

Laravel делает взаимодействие с базой данных невероятно простым благодаря гибкому конструктору запросов. Такие возможности достигаются используя Eloquent ORM, который позволяет работать с различными базами данных, такими как:

  • MySQL
  • PostgreSQL
  • SQLite
  • SQL Server

Конфигурация

Конфигурация базы данных для вашего приложения располагается в config/database.php. В этом файле вы можете определить все соединения с базой данных, а ещё указать какое соединения неоходимо использовать по умолчанию. Примеры для большинства поддерживаемый баз данных находятся в этом файле.

По умолчанию, конфигурация окружения готова к использованию с Laravel Homestead, которое является удобной виртуальной машиной для локальной разработки на Ларавел. Вы можете свободно изменить конфигурацию так, как это необходимо для вашей локальной базы данных.

Конфигурация SQLite

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

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

Чтобы включить ограничения внешнего ключа для соединения SQLite, вам необходимо добавить опцию foreign_key_constraints в ваш файл конфигурации config/database.php:

'sqlite' => [
    // ...
    'foreign_key_constraints' => true,
],

Конфигурация с использованием URLs

Обыкновенно, соединия базы данных настраиваются с использованием нескольких значений конфигураций, таких как host, database, username, password и другие. Каждое из этих значений имеет соотвествующие значения среды. Это означает, что при настройке соединения вашей базы данных на сервере, вам необходимо несколькими переменными среды.

Некоторые провайдеры бд, такие как Heroku, предоставляют единый "URL" для бд, который содержит всю информацию для базы данных в простой строке. Пример URL базы данных может выглядеть таким образом:

driver://username:password@host:port/database?options

Эти URLs обычно придерживаются типовой схемы:

driver://username:password@host:port/database?options

Для удобства, Laravel поддерживает эти URL как альтернативу для настройки вашей базы данных с несколькими опциями конфигурации. Если url или соотвествующая переменная среды DATABASE_URL присутствует, она будет использована для того, чтобы извлечь информацию о соединении базы данных и другие данные.

Чтение и написание коннекторов

Иногда вы можете использовать одно соединение базы данных для выражений с SELECT и другое для INSERT, UPDATE, и DELETE. Ларавел позволяет реализовать задуманное легко, нужное соединение будет всегда использовано вне зависимости от того, что вы используете: запросы, конструктор запросов или 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'    => '',
],

Надо отметить, что 3 ключа были добавлены в массив конфигурации: read, write и sticky. Ключи read и write имеют массив значений, содержащий одиночный ключ host. Остальные опции базы данных для соединений read и write будут добавлены из основного массива mysql.

Вам лишь необходимо разместить элеменыт вы массивах read и write, если вы хотите переписать значения из основного массива. Поэтому, в этом случае, 192.168.1.1 будет использовано в качестве хоста для соединения read, в то время как 192.168.1.3 будет использовано для соединения write. Учётные данные базы данных, префикс, набор символов и другие опции в основном массиве mysql будут доступны для обоих соединений.

Опция sticky

Опция sticky это значение optional, которое может быть использовано для того, чтобы разрешить мгновенное чтение записей, которые были записаны в течение текущего цикла запроса. Если опция sticky включена и операция write была выполнена для бд в течение текущего цикла, любые последующие операции read будут использовать соединение write. Это является гарантией того, что данные записанные во время запроса могут быть прочитаны из бд во время того же запроса. Вам решать, стоит ли включать такую логику для вашего приложения.

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

При использовании нескольких соединений, вы можете получить доступ к соединению через метод connection для фасада DB. В метод connection передаётся name, которое должно соотвествовать одному из соединений, перечисленных в вашем файле конфигурации config/database.php:

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

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

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

Запуск 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 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 результатов. Каждый результат внутри массива будет stdClass объектом PHP, что позволяет вам получить конкретное значениеs:

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

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

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

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

Выполнение выражений с Insert

Чтобы выполнить выражение с insert, вы можете использовать метод insert для фасада DB. Как и для select, этот метод берёт выражение SQL в качестве первого аргумента и связывание в качестве второго:

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 нужно использовать для удаления записей из базы данных. Как и в случае с update, вернётся число затронутых строк:

$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
{
    /**
     * 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 для запуска набора операций внутри транзакции бд. Если появилось исключение внутри замыкания транзакции, то будет автоматически откат в исходную позицию. Если Closure выполняется успешно, транзация будет автоматически зафиксирована. Вам не нужно беспокоиться об откатах в исходную позицию или комитах при использовании метода transaction:

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.