В 6-ом уроке мы изучимв один из ключевых аспектов Symfony, это работу с базами данных через Doctrine ORM. Этот урок станет фундаментом для всех ваших будущих проектов, где требуется хранение, управление и запросы к данным. Мы разберем:
- Установку и настройку Doctrine,
- Создание сущностей (Entities) и репозиториев (Repositories),
- Миграции (make:migration и doctrine:migrations:migrate),
- Основы DQL (Doctrine Query Language).
Установка и настройка Doctrine
Doctrine это ORM (Object-Relational Mapper), который превращает таблицы базы данных в объекты PHP. Вместо написания SQL-запросов вы работаете с классами и методами. Это удобно, безопасно и поддерживает принципы ООП.
Установка Doctrine
- Добавляем Doctrine в проект через Composer:
composer require symfony/orm-pack composer require --dev symfony/maker-bundle
Пакет orm-pack
добавляет Doctrine и его зависимости, а maker-bundle
поможет генерировать сущности.
- Настройка подключения к БД в файле
.env
:
DATABASE_URL="mysql://root:password@127.0.0.1:3306/symfony_db?serverVersion=8.0"
Замените root
, password
, symfony_db
и serverVersion
на свои значения.
Doctrine поддерживает MySQL, PostgreSQL, SQLite и другие СУБД.
- Проверка подключения:
php bin/console doctrine:database:create
Если видите сообщение Created database symfony_db
, всё готово!
Сущности (Entities) и репозитории (Repositories)
Создание сущности
Сущность это PHP-класс, который отображается на таблицу в БД.
Пример: Создадим сущность Product
.
php bin/console make:entity Product
Следуйте подсказкам и добавьте поля:
name
(string, 255),price
(float),description
(text).
Результат:
// src/Entity/Product.php namespace App\Entity; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: ProductRepository::class)] class Product { #[ORM\Id] #[ORM\GeneratedValue] #[ORM\Column] private ?int $id = null; #[ORM\Column(length: 255)] private ?string $name = null; #[ORM\Column] private ?float $price = null; #[ORM\Column(type: 'text')] private ?string $description = null; // Геттеры и сеттеры... }
Репозитории
Репозиторий это класс для работы с данными сущности. Doctrine автоматически генерирует его при создании сущности.
Пример использования:
// src/Repository/ProductRepository.php namespace App\Repository; use App\Entity\Product; use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository; use Doctrine\Persistence\ManagerRegistry; class ProductRepository extends ServiceEntityRepository { public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Product::class); } // Кастомный метод для поиска товаров дороже указанной цены public function findProductsMoreExpensiveThan(float $price): array { return $this->createQueryBuilder('p') ->andWhere('p.price > :price') ->setParameter('price', $price) ->orderBy('p.price', 'ASC') ->getQuery() ->getResult(); } }
Миграции
Миграции это версионирование структуры БД. Они позволяют безопасно применять изменения схемы данных.
Генерация миграции
После изменения сущности (например, добавления поля isPublished
):
php bin/console make:migration
Doctrine сравнит текущую структуру БД с маппингом сущностей и сгенерирует SQL-запрос в файле migrations/Version20230401...php
.
Применение миграции
php bin/console doctrine:migrations:migrate
Всегда проверяйте сгенерированный SQL перед выполнением!
Основы DQL (Doctrine Query Language)
DQL это объектно-ориентированный диалект SQL, работающий с сущностями, а не таблицами.
Пример DQL-запроса
Найдем товары с ценой выше 1000:
// Внутри ProductRepository public function findExpensiveProducts(): array { $entityManager = $this->getEntityManager(); $query = $entityManager->createQuery( 'SELECT p FROM App\Entity\Product p WHERE p.price > 1000 ORDER BY p.price ASC' ); return $query->getResult(); }
DQL или Query Builder
- DQL подходит для сложных запросов.
- Query Builder удобен для поэтапного построения запроса:
$queryBuilder = $this->createQueryBuilder('p') ->where('p.price > :price') ->setParameter('price', 1000) ->orderBy('p.price', 'ASC') ->getQuery();
Практические задачи
- Создайте сущность
User
с полями:email
(string),createdAt
(datetime). - Добавьте миграцию для новой сущности и выполните ее.
- Напишите DQL-запрос, который выбирает пользователей, зарегистрированных после 1 января 2023 года.
- Создайте метод в репозитории для поиска товаров по части названия (используйте
LIKE
).
Пример решения задачи 4
// В ProductRepository public function searchByName(string $keyword): array { return $this->createQueryBuilder('p') ->andWhere('p.name LIKE :keyword') ->setParameter('keyword', "%{$keyword}%") ->getQuery() ->getResult(); }
Вы освоили основы Doctrine ORM, от создания сущностей до работы с миграциями и DQL. Теперь ваши приложения могут взаимодействовать с БД на профессиональном уровне. Не останавливайтесь, полный курс по Symfony для начинающих ждет вас.