Создание, чтение, изменение, удаление
Сущность сама себя не сохраняет. Этим занимается EntityManager: ему сообщают, какие объекты нужно записать, а он выполняет запросы. Читают данные через репозиторий — класс, созданный вместе с сущностью.
Создание записи
use App\Entity\Post;
use Doctrine\ORM\EntityManagerInterface;
#[Route('/blog/create', name: 'blog_create')]
public function create(EntityManagerInterface $em): Response
{
$post = new Post();
$post->setTitle('Первая статья');
$post->setBody('Текст статьи');
$em->persist($post);
$em->flush();
return new Response('Создана статья №' . $post->getId());
}persist() сообщает Doctrine о новом объекте, flush() выполняет запрос INSERT. До вызова flush() в базе ничего не меняется.
Чтение
use App\Repository\PostRepository;
#[Route('/blog', name: 'blog_index')]
public function index(PostRepository $posts): Response
{
return $this->render('blog/index.html.twig', [
'posts' => $posts->findAll(),
]);
}| Метод | Что возвращает |
|---|---|
find($id) | Запись по идентификатору или null |
findAll() | Все записи |
findBy([...]) | Записи по условиям |
findOneBy([...]) | Первую подходящую запись или null |
count([...]) | Количество |
$latest = $posts->findBy(
['published' => true],
['id' => 'DESC'],
10,
);Аргументы findBy(): условия, сортировка, сколько записей взять.
Сущность прямо в аргументах
Если в адресе есть {id}, а в аргументах метода — сущность, Symfony найдёт запись сам. Не нашёл — вернёт ошибку 404:
#[Route('/blog/{id}', name: 'blog_show')]
public function show(Post $post): Response
{
return $this->render('blog/show.html.twig', ['post' => $post]);
}Для поиска по другому полю его указывают в адресе: /blog/{slug:post}.
Изменение
Объект, полученный из базы, Doctrine уже отслеживает. Достаточно изменить его и вызвать flush():
#[Route('/blog/{id}/publish', name: 'blog_publish', methods: ['POST'])]
public function publish(Post $post, EntityManagerInterface $em): Response
{
$post->setPublished(true);
$em->flush();
return $this->redirectToRoute('blog_show', ['id' => $post->getId()]);
}persist() здесь не нужен.
Удаление
$em->remove($post);
$em->flush();Несколько изменений сразу
flush() записывает все накопленные изменения одной транзакцией: либо выполнятся все запросы, либо ни один.
$em->persist($post);
$em->persist($comment);
$author->setPostCount($author->getPostCount() + 1);
$em->flush();Частая ошибка
Без flush() данные не сохраняются: persist() только ставит объект в очередь. Код отработает без ошибок, а в базе ничего не появится. И наоборот — не вызывайте flush() в цикле после каждой записи: один вызов после цикла выполнится во много раз быстрее.