База данных · PPA

База данных — обзор

Работа с БД в Winter построена на PPA (PHP Persistence API) — слое репозиториев поверх пакета CDO. Вы описываете репозиторий и сущность, а PPA даёт типобезопасный конструктор запросов, гидрацию в объекты и готовые CRUD-операции — без сырого SQL и ручного PDO.

Слой Ppa\StereotypeПоверх CDO (PDO)БД PostgreSQL · MySQL · Oracle

Что такое PPA и зачем

PPA — это ORM-слой фреймворка: репозитории, сущности и конструктор запросов. ORM (object-relational mapping) сопоставляет строки таблиц с объектами PHP.

Проблема. Голый PDO означает SQL-строки, разбросанные по коду, ручной биндинг параметров, риск инъекций и результат в виде безликих массивов. Одну и ту же выборку приходится собирать заново в каждом месте, а типов нет.

Решение. PPA даёт репозиторий — класс, привязанный к таблице, с fluent-API запросов (where, join, limit) и защитой от инъекций, а результат гидрирует в типизированные сущности. CRUD-операции (insert/update/delete) уже готовы. Об этом и раздел.

Как устроено

Три составляющие работают вместе:

text
Repository   — класс, привязанный к таблице; конструктор запросов + CRUD
  │  использует

Entity       — типизированный объект строки (маппинг колонок атрибутами)
  │  выполняется через

DbConfig     — параметры подключения (драйвер, хост, БД, пул)
  • Репозиторий — где вы пишете запросы и операции записи.
  • Сущность — во что гидрируется результат (см. Сущности).
  • Конфиг подключения — класс с параметрами БД (см. Подключение).

Стереотипы репозиториев

Репозиторий наследует один из стереотипов — по объёму нужного доступа:

Стереотип Что умеет Когда
Repository Чтение + запись + конструктор запросов Большинство случаев
RepositoryView Только чтение Вьюхи БД, отчёты, проекции
RepositoryCrud Только запись Append-only таблицы, импорт
CteRepo Ad-hoc чтение без фиксированной таблицы Разовые запросы, инстанцируется напрямую

Быстрый пример

Репозиторий — это несколько строк: конфиг, сущность, имя таблицы.

main/UserRepository.php
<?php

namespace Main;

use Flytachi\Winter\K2\Ppa\Stereotype\Repository;

class UserRepository extends Repository
{
  protected string $dbConfigClassName = MainDbConfig::class;
  protected string $entityClassName   = User::class;
  public static string $table         = 'users';
}

Дальше — чтение через конструктор запросов и статические шорткаты:

php
use Flytachi\Winter\K2\Ppa\Repository\Qb;

// Статический шорткат по первичному ключу
$user = UserRepository::findById(42);

// Fluent-конструктор запросов
$users = UserRepository::instance('u')
  ->joinLeft('orders o', 'u.id = o.user_id')
  ->where(Qb::eq('u.status', 'active'))
  ->orderBy('u.id DESC')
  ->limit(20)
  ->findAll();

И запись:

php
$repo = new UserRepository();
$id   = $repo->insert(['name' => 'Alice', 'email' => 'alice@example.com']);
$repo->update(['status' => 'inactive'], Qb::lt('last_login', '2024-01-01'));

Скаффолд

Репозиторий, сущность и конфиг генерируются командой make: php call make -r .User (репозиторий), -e .User (сущность), -D .Main (конфиг БД).

Разделение с пакетом CDO

PPA — это слой репозиториев поверх CDO. Низкоуровневый конструктор запросов, драйверы и типобезопасные обёртки над PDO живут в пакете CDO — туда идём за глубиной по SQL-построению. Эти доки покрывают репозиторный API PPA.

Что дальше в разделе

Страница О чём
Подключение Класс DbConfig, драйверы, .env, пул соединений
Сущности Маппинг колонок атрибутами, связи, ключи
Конструктор запросов select/where/join/groupBy/orderBy, Qb::
CRUD insert/update/delete/upsert, статические finders
Пагинация Wrapper::paginator, offset/cursor
Миграции call db migrate, #[Migratable], генерация схемы