fbpx

Encje doctrinowe i relacje – praktyczne wykorzystanie

Encje doctrinowe i relacje – praktyczne wykorzystanie

Przyszedł czas na kolejną część cyklu o encjach doctrinowych. W ostatnim poście poznałeś już podstawy jak używać Doctrina. Wiesz jak konfigurować encje i podstawowe pola. Przyszedł czas osiągnąć kolejny poziom wtajemniczenia. W tym poście poznasz jak w Symfony 3 wykorzystać encje doctrinowe i relacje.

Encje doctrinowe i relacje

Bardzo rzadko występują modele baz danych, w których między tabelami nie występują relacje. Pokusiłabym się nawet, że w poważnych projektach nigdy nie znajdziemy takich modeli. Dlaczego? Bo nawet w świecie rzeczywistym ciężko znaleźć elementy, które nie wchodzą w relacje z żadnym innym elementem np. jabłko, rośnie na drzewie, które kwitnie, a kwiat zostaje zapylony przez pszczołę. Modelując taką sytuację, od razu widzimy, że zwykłe jabłko, będzie mieć relację z drzewem, kwiatem i pszczołą. Teraz Ty pomyśl, czy znajdziesz przykład elementu świata rzeczywistego, który nie posiada żadnych relacji? Jeśli tak to daj znać w komentarzu, podyskutujmy na ten temat, bo jest on bardzo ciekawy.

Podczas projektowania rozważałam dwa systemy bazy dancyh – MySQL oraz PostgreSQL.Oba te systemy zaliczamy do grupy relacyjnych baz danych. Oprócz nich wyróżniamy również bazy obiektowe i strumieniowe. Jednak to właśnie relacyjne są najbardziej rozpowszechnione i najczęściej używane. Mówiąc o relacyjnych bazach danych, ciężko nie wspomnieć o normalizacji. Są to zasady projektowania bazy danych, takie best practise. Jednak jest to bardzo obszerny temat na inny post.

Encje doctrinowe i relacje dają nam wiele możliwości definiowania stryktury, w zależności, jaki typ relacji chcemy zdefiniować, zrobimy to w różny sposób. Przykłady relacji będą pochodzić z projektu, który rozwijam w ramach konkursu Daj się poznać 2017. Kod znajdziesz na gihubie.

jeden – jeden

W moim projekcie relacja 1-1 zachodzi między użytkownikiem a jego adresem (user-userAdress). Ta relacja wyszła w tracie pracy. Jak to wygląda w kodzie? Już piszę. TargetEntity to encja, która wchodzi w relację, inversedBy i mappedBy mówią nam, które pole będzie odpowiadało drugiej stronie relacji. Cascade przy adresie określa, że przy usunięciu oraz utrwaleniu Usera nastąpi analogiczne działanie na adresie, określa to również onDelete = “CASCADE” po drugiej stronie relacji.

/**
 * @ORM\OneToOne(targetEntity="Backend\UserBundle\Entity\UserAddress", mappedBy="customer", cascade={"persist", "remove"})
 * @var CustomerAddress
 */
private $address;
/**
 * @ORM\OneToOne(targetEntity="Backend\UserBundle\Entity\User", inversedBy="address")
 * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
 * @var User
 */
private $user;

jeden – wiele

Jeden do wiele to chyba najczęściej używana relacja w moim projekcie i nie tylko np. wydarzenie może być przypisane do wielu grafików (event-charts), jeden organizator może organizować wiele wydarzeń (event-organizer). Elementy adnotacji są takie same jak w relacji 1-1 opisane powyżej.

/**
 * @ORM\ManyToOne(targetEntity="Backend\EventBundle\Entity\Organizer", inversedBy="events")
 * @ORM\JoinColumn(name="organizer_id", referencedColumnName="id")
 * @var Organizer
 */
private $organizer;
/**
 * @ORM\OneToMany(targetEntity="Backend\EventBundle\Entity\Event", mappedBy="organizer", cascade={"persist", "remove"})
 * @var ArrayCollection|Events[]
 */
private $events;

wiele – wiele

To najbardziej skomplikowana relacja do skonfigurowania, ale oczywiście do zrealizowania. W moim przypadku zachodzi między wydarzeniem a jego ocenami (event-rate).

    /**
     * @ManyToMany(targetEntity="Backend\EventBundle\Entity\Rate")
     * @JoinTable(name="events_rates",
     *      joinColumns={@JoinColumn(name="rate_id", referencedColumnName="id")},
     *      inverseJoinColumns={@JoinColumn(name="event_id", referencedColumnName="id", unique=true)}
     *      )
     */
    private $rates;

Jednak osobiście polecam stworzyć obiekt EventRate, który wchodzi w relacje jeden do wielu z wydarzeniem (event) i oceną (rate). Mamy większą kontrolę nad obiektami i tabelami.

Wszystkie przykłady są definiowane w adnotacji. Taki sam zapis możemy stworzyć w formie pliku yml dla każdej encji.

Kod, który podałam w przykładach, jeszcze w tym tygodniu pojawi się na githubie. Jeśli masz jeszcze jakieś pytania albo problemy w swoim projekcie napisz w komentarzu, chętnie pomogę, a może razem wpadniemy na jakieś rozwiązanie. Encje doctrinowe i i relacje między nimi to wiedza, którą powinien posiadać każdy programista chcący pracować z Symfony i Doctrinem.

Zgarnij darmowy ebook i cotygodniową dawkę wiedzy

.
Magdalena Limanówka-Kuciel
magdalena@panizkomputerem.pl

Jestem programistką, która lubi mieć ręce pełne roboty. Do życia potrzebuje komputera z internetem i kubka gorącej kawy. Więcej na stronie o mnie.