РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
195 of 258 menu

Параметр fetch атрибута ManyToOne

Параметр fetch атрибута ManyToOne задаёт стратегию загрузки связанной сущности в Doctrine. Он определяет, когда именно будет выполнен SQL-запрос за связанными данными: сразу при загрузке основной сущности или лениво, в момент первого обращения к связи. По умолчанию используется значение LAZY.

Параметр принимает одно из значений: LAZY, EAGER или EXTRA_LAZY. Стратегия LAZY откладывает запрос до момента обращения, EAGER загружает связь сразу вместе с основной сущностью, а EXTRA_LAZY загружает данные только при реальном обращении к элементам коллекции.

Синтаксис

#[ManyToOne(targetEntity: Entity::class, fetch: 'LAZY')]

Пример

Давайте создадим сущность Article со связью ManyToOne на сущность Category и стратегией загрузки LAZY по умолчанию:

<?php namespace AppEntity; use AppRepositoryCategoryRepository; use DoctrineORMMapping as ORM; #[ORMEntity(repositoryClass: CategoryRepository::class)] class Category { #[ORMId] #[ORMGeneratedValue] #[ORMColumn] private ?int $id = null; #[ORMColumn(length: 255)] private ?string $title = null; public function getId(): ?int { return $this->id; } public function getTitle(): ?string { return $this->title; } public function setTitle(string $title): static { $this->title = $title; return $this; } } ?>

Теперь создадим сущность Article со связью на Category:

<?php namespace AppEntity; use AppRepositoryArticleRepository; use DoctrineORMMapping as ORM; #[ORMEntity(repositoryClass: ArticleRepository::class)] class Article { #[ORMId] #[ORMGeneratedValue] #[ORMColumn] private ?int $id = null; #[ORMColumn(length: 255)] private ?string $title = null; #[ORMManyToOne(targetEntity: Category::class, fetch: 'LAZY')] #[ORMJoinColumn(nullable: false)] private ?Category $category = null; public function getId(): ?int { return $this->id; } public function getTitle(): ?string { return $this->title; } public function setTitle(string $title): static { $this->title = $title; return $this; } public function getCategory(): ?Category { return $this->category; } public function setCategory(?Category $category): static { $this->category = $category; return $this; } } ?>

При стратегии LAZY запрос к таблице category выполнится только при вызове метода getCategory:

<?php namespace AppController; use AppEntityArticle; use DoctrineORMEntityManagerInterface; use SymfonyBundleFrameworkBundleControllerAbstractController; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentRoutingAttributeRoute; class ArticleController extends AbstractController { #[Route('/article/{id}', name: 'article_show')] public function show(int $id, EntityManagerInterface $em): Response { $article = $em->getRepository(Article::class)->find($id); // SQL-запрос за категорией выполнится только здесь $title = $article->getCategory()->getTitle(); return new Response($title); } } ?>

Результат выполнения кода для адреса /article/1:

"abcde"

Пример

Давайте изменим стратегию на EAGER, чтобы категория загружалась сразу вместе со статьёй:

<?php namespace AppEntity; use AppRepositoryArticleRepository; use DoctrineORMMapping as ORM; #[ORMEntity(repositoryClass: ArticleRepository::class)] class Article { #[ORMId] #[ORMGeneratedValue] #[ORMColumn] private ?int $id = null; #[ORMColumn(length: 255)] private ?string $title = null; #[ORMManyToOne(targetEntity: Category::class, fetch: 'EAGER')] #[ORMJoinColumn(nullable: false)] private ?Category $category = null; public function getId(): ?int { return $this->id; } public function getTitle(): ?string { return $this->title; } public function setTitle(string $title): static { $this->title = $title; return $this; } public function getCategory(): ?Category { return $this->category; } public function setCategory(?Category $category): static { $this->category = $category; return $this; } } ?>

Теперь при выборке статьи Doctrine сразу выполнит JOIN и подгрузит категорию одним запросом:

<?php namespace AppController; use AppEntityArticle; use DoctrineORMEntityManagerInterface; use SymfonyBundleFrameworkBundleControllerAbstractController; use SymfonyComponentHttpFoundationResponse; use SymfonyComponentRoutingAttributeRoute; class ArticleController extends AbstractController { #[Route('/article/{id}', name: 'article_show')] public function show(int $id, EntityManagerInterface $em): Response { $article = $em->getRepository(Article::class)->find($id); // Категория уже загружена, дополнительного запроса не будет $title = $article->getCategory()->getTitle(); return new Response($title); } } ?>

Результат выполнения кода для адреса /article/1:

"abcde"

Смотрите также

  • атрибут ManyToOne,
    который задаёт связь многие-к-одному
  • параметр targetEntity,
    который указывает целевую сущность связи
  • параметр inversedBy,
    который задаёт обратную сторону связи
  • параметр cascade,
    который задаёт каскадные операции
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить