Symfony — работа с БД (Doctrine)

Работа с базой данных Symfony. Работа с ОРМ Doctrine.

Всё то же самое, с небольшим отличиями, есть в официальном руководстве:
https://symfony.com/doc/current/doctrine.html

Или на русском:
https://symfony.ru/doc/current/doctrine.html

В официальном руководстве о чем-то говорится больше, что-то пропускается в виду того, что вы сами должны догадаться. Здесь ниже я попробовал упростить и может быть более точно указать что и где нужно поставить.

Официальное руководство все же стоит почитать, там разжевывают некоторые моменты.

Устанавливаем инструменты для работы с БД

composer require symfony/orm-pack
composer require --dev symfony/maker-bundle

Создание БД

Создаем базу данных

php bin/console doctrine:database:create

Команды доктрины

bin/console list doctrine

Установим maker

composer require doctrine maker

Создание таблиц и сущностей в них

Создаем сущность

bin/console make:entity

Отвечаем на вопросы, подбирая подходящие для себя параметры.

Если понадобится в дальнейшем добавить новое поле в таблицу, то используем эту же команду.

Создаем (или обновляем) таблицу миграции для последующего внедрения в БД

php bin/console make:migration

В консоли будет указан файл, что-то вроде:

Next: Review the new migration "src/Migrations/Version20200309102744.php"

В нём будут параметры создания таблицы.

Запустим создание (или обновления) таблицы в БД:

php bin/console doctrine:migrations:migrate

Эту же команду стоит запустить на продакшене для обновления таблиц.

Если требуется пересоздать сущности, например в том случае, когда добавление происходит вручную через файл:

bin/console make:entity --regenerate

Контроллер

Контроллер нужен для сохранения объектов в базе данных.

php bin/console make:controller ProductController

Заменяем содержимое на

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;

use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Response;

class ProductController extends AbstractController
{
    /**
     * @Route("/product", name="create_product")
     */
    public function createProduct(): Response
    {
        // you can fetch the EntityManager via $this->getDoctrine()
        // or you can add an argument to the action: createProduct(EntityManagerInterface $entityManager)
        $entityManager = $this->getDoctrine()->getManager();

        $product = new Product();
        $product->setName('Keyboard');
        $product->setPrice(1999);
        $product->setDescription('Ergonomic and stylish!');

        // tell Doctrine you want to (eventually) save the Product (no queries yet)
        $entityManager->persist($product);

        // actually executes the queries (i.e. the INSERT query)
        $entityManager->flush();

        return new Response('Saved new product with id '.$product->getId());
    }
}

Добавляем в конец адресной строки сайта слово product и затем открываем:

http://localhost/symfony-svelte/public/product

Это создаст первую строку БД.

Проверить можно через консоль:

php bin/console doctrine:query:sql 'SELECT * FROM product'

Получение объекта из БД

В том же файле ProductController.php добавим:

/**
 * @Route("/product/{id}", name="product_show")
 */

public function show($id)
{
    $product = $this->getDoctrine()
        ->getRepository(Product::class)
        ->find($id);

    if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$id
        );
    }

    return new Response('Check out this great product: '.$product->getName());

    // or render a template
    // in the template, print things with {{ product.name }}
    // return $this->render('product/show.html.twig', ['product' => $product]);
}

И перейдем:

http://localhost/symfony-svelte/public/product/1

Увидим получение указанных данных выше. В данном случае поля Name.

SensioFrameworkExtraBundle

Для автоматизации и упрощения процесса установим фреймворк:

composer require sensio/framework-extra-bundle

Упростим метод public function show(Product $product)

    /**
     * @Route("/product/{id}", name="product_show")
     */

    public function show(Product $product)
    {
        return new Response('Check out this great product: '.$product->getPrice());
    }

И снова откроем страницу:

http://localhost/symfony-svelte/public/product/1

Получим то же самое, что и в первом варианте.

Больше опций здесь:
https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html

Обновление продукта

/**
 * @Route("/product/edit/{id}")
 */

public function update($id)
{
    $entityManager = $this->getDoctrine()->getManager();
    $product = $entityManager->getRepository(Product::class)->find($id);

    if (!$product) {
        throw $this->createNotFoundException(
            'No product found for id '.$id
        );
    }

    $product->setName('New product name!');
    $entityManager->flush();

    return $this->redirectToRoute('product_show', [
        'id' => $product->getId()
    ]);
}
http://localhost/symfony-svelte/public/product/edit/1

Удаление

    /**
    * @Route("/product/remove/{id}")
    */

    public function remove($id)
    {
        $entityManager = $this->getDoctrine()->getManager();
        $product = $entityManager->getRepository(Product::class)->find($id);

        if (!$product) {
            throw $this->createNotFoundException(
                'No product found for id '.$id
            );
        }

        $entityManager->remove($product);
        $entityManager->flush();
    }

Открываем:

http://localhost/symfony-svelte/public/product/remove/1
Метки:

Привет. Ты находишься на моём сайте. Я разработчик. Здесь я делюсь своими наработками и знаниями. Спрашивай в комментариях, если тебе что-то не понятно или пиши, если есть что добавить.

Если вам пригодилась информация, вы можете поблагодарить автора сайта символическим пожертвованием:

Добавить комментарий

Напишите свой комментарий, если вам есть что добавить/поправить/спросить по теме текущей статьи: "Symfony — работа с БД (Doctrine)"
Если вам нужно добавить участок кода ставьте его между тегами <code></code>