Whatsapp Telegram Telegram Call Anrufen

Doctrine ORM in Symfony


Doctrine ORM (Object-Relational Mapping) ist ein leistungsstarkes Tool, das die Verwaltung von Datenbanken in Symfony-Anwendungen erheblich vereinfacht. Es ermöglicht Entwicklern, Datenbankoperationen durch die Arbeit mit PHP-Objekten durchzuführen, anstatt direkt SQL-Abfragen zu schreiben. In diesem Artikel werden wir die folgenden Themen ausführlich behandeln:

  1. Einrichtung von Doctrine
  2. Erstellen von Entitäten und Zuordnung zu Datenbanktabellen
  3. Datenbankmigrationen mit Doctrine Migrations
  4. CRUD-Operationen
  5. Abfragen mit Doctrine Query Builder und DQL
  6. Verwaltung von Beziehungen (OneToOne, OneToMany, ManyToMany)
  7. Arbeiten mit Repositories


1. Einrichtung von Doctrine

1.1 Installation von Doctrine

Wenn Sie ein neues Symfony-Projekt mit dem --full Flag erstellen, ist Doctrine normalerweise bereits installiert. Falls nicht, können Sie es mit dem folgenden Composer-Befehl hinzufügen:

composer require orm

Dieser Befehl installiert das Doctrine ORM und die notwendigen Pakete.

1.2 Datenbankkonfiguration

Doctrine benötigt Informationen über die Datenbankverbindung. Diese werden in der .env Datei Ihres Projekts definiert.

Beispiel .env Datei:

DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name"
  • db_user: Ihr Datenbankbenutzername
  • db_password: Ihr Datenbankpasswort
  • 127.0.0.1: Host der Datenbank (lokal)
  • 3306: Standardport für MySQL
  • db_name: Name Ihrer Datenbank

1.3 Erstellen der Datenbank

Nachdem Sie die Datenbankverbindung konfiguriert haben, können Sie die Datenbank erstellen:

php bin/console doctrine:database:create

2. Erstellen von Entitäten und Zuordnung zu Datenbanktabellen

2.1 Was ist eine Entität?

Eine Entität ist eine PHP-Klasse, die ein Datenbankobjekt repräsentiert. Sie enthält Eigenschaften, die den Spalten der Datenbanktabelle entsprechen, und Annotations, die die Zuordnung definieren.

2.2 Erstellen einer Entität mit dem Maker-Bundle

Das Maker-Bundle vereinfacht die Erstellung von Entitäten.

Installation des Maker-Bundles (falls nicht bereits installiert):

composer require symfony/maker-bundle --dev

Erstellen einer Entität:

php bin/console make:entity Product

Der Befehl startet einen interaktiven Prozess.

Beispiel:

New property name (press <return> to stop adding fields):
 > name

Field type (enter ? to see all types) [string]:
 >

Field length [255]:
 >

Can this field be null in the database (nullable) (yes/no) [no]:
 >

Add another property? Enter the property name (or press <return> to stop adding fields):
 > price

Field type (enter ? to see all types) [string]:
 > float

Can this field be null in the database (nullable) (yes/no) [no]:
 >

Add another property? Enter the property name (or press <return> to stop adding fields):
 >

2.3 Die generierte Entitätsklasse

Nach dem Erstellen sieht die Klasse Product etwa so aus:

// src/Entity/Product.php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity()
 */
class Product
{
    /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $name;

    /**
     * @ORM\Column(type="float")
     */
    private $price;

    // Getter und Setter Methoden...

    public function getId(): ?int
    {
        return $this->id;
    }

    // ... weitere Getter und Setter
}

2.4 Mappings und Annotations

  • @ORM\Entity(): Kennzeichnet die Klasse als Entität.
  • @ORM\Id: Markiert die Eigenschaft als Primärschlüssel.
  • @ORM\GeneratedValue: Der Wert wird automatisch generiert (Auto-Inkrement).
  • @ORM\Column: Definiert die Spalte in der Datenbank mit Typ und optionalen Eigenschaften.


3. Datenbankmigrationen mit Doctrine Migrations

3.1 Installation von Doctrine Migrations

Doctrine Migrations verwaltet Schemaänderungen in der Datenbank.

composer require doctrine/migrations

3.2 Erstellen einer Migration

Nachdem Sie Ihre Entitäten erstellt oder geändert haben, müssen Sie die Änderungen in die Datenbank übertragen.

Schritt 1: Migration generieren

php bin/console make:migration

Dieser Befehl erzeugt eine neue Migrationsdatei im Verzeichnis migrations/.

Schritt 2: Migration ausführen

php bin/console doctrine:migrations:migrate

Bestätigen Sie die Ausführung, wenn Sie dazu aufgefordert werden.

3.3 Inhalt einer Migrationsdatei

Eine Migrationsdatei enthält Methoden up() und down(), die SQL-Anweisungen zum Aktualisieren und Rückgängigmachen der Schemaänderungen enthalten.

Beispiel:

public function up(Schema $schema): void
{
    $this->addSql('CREATE TABLE product (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(255) NOT NULL, price DOUBLE PRECISION NOT NULL, PRIMARY KEY(id))');
}

public function down(Schema $schema): void
{
    $this->addSql('DROP TABLE product');
}

4. CRUD-Operationen

CRUD steht für Create, Read, Update, Delete. Doctrine ermöglicht es, diese Operationen einfach durchzuführen.

4.1 Entity Manager

Der Entity Manager (EntityManagerInterface) ist für das Verwalten von Entitäten zuständig.

Einbindung in den Controller:

use Doctrine\ORM\EntityManagerInterface;

public function index(EntityManagerInterface $entityManager)
{
    // ...
}

4.2 Erstellen (Create)

Beispiel:

public function create(EntityManagerInterface $entityManager)
{
    $product = new Product();
    $product->setName('Laptop');
    $product->setPrice(999.99);

    $entityManager->persist($product);
    $entityManager->flush();

    return new Response('Produkt erstellt mit der ID ' . $product->getId());
}
  • persist(): Bereitet das Objekt zum Speichern vor.
  • flush(): Führt die Änderungen in der Datenbank aus.

4.3 Lesen (Read)

Beispiel:

use App\Repository\ProductRepository;

public function show(ProductRepository $productRepository, $id)
{
    $product = $productRepository->find($id);

    if (!$product) {
        throw $this->createNotFoundException('Produkt nicht gefunden');
    }

    return new Response('Produkt: ' . $product->getName());
}

4.4 Aktualisieren (Update)

Beispiel:

public function update(EntityManagerInterface $entityManager, $id)
{
    $product = $entityManager->getRepository(Product::class)->find($id);

    if (!$product) {
        throw $this->createNotFoundException('Produkt nicht gefunden');
    }

    $product->setPrice(899.99);
    $entityManager->flush();

    return new Response('Produkt aktualisiert');
}

4.5 Löschen (Delete)

Beispiel:

public function delete(EntityManagerInterface $entityManager, $id)
{
    $product = $entityManager->getRepository(Product::class)->find($id);

    if (!$product) {
        throw $this->createNotFoundException('Produkt nicht gefunden');
    }

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

    return new Response('Produkt gelöscht');
}

5. Abfragen mit Doctrine Query Builder und DQL

5.1 Doctrine Query Language (DQL)

DQL ist eine objektorientierte Abfragesprache, die SQL ähnelt, aber mit Entitäten arbeitet.

Beispiel:

$entityManager = $this->getDoctrine()->getManager();

$query = $entityManager->createQuery(
    'SELECT p
    FROM App\Entity\Product p
    WHERE p.price > :price'
)->setParameter('price', 500);

$products = $query->getResult();

5.2 Query Builder

Der Query Builder ermöglicht den schrittweisen Aufbau von Abfragen.

Beispiel:

$repository = $entityManager->getRepository(Product::class);

$query = $repository->createQueryBuilder('p')
    ->where('p.price > :price')
    ->setParameter('price', 500)
    ->orderBy('p.price', 'ASC')
    ->getQuery();

$products = $query->getResult();

5.3 Verwendung von Parametern

  • setParameter(): Bindet einen Wert an einen Platzhalter.
  • Sicherheitsvorteil: Schützt vor SQL-Injection.

5.4 Paginierung

Mit dem Query Builder können Sie Paginierung einfach implementieren.

Beispiel:

$page = 1;
$pageSize = 10;

$query = $repository->createQueryBuilder('p')
    ->setFirstResult(($page - 1) * $pageSize)
    ->setMaxResults($pageSize)
    ->getQuery();

$products = $query->getResult();

6. Verwaltung von Beziehungen (OneToOne, OneToMany, ManyToMany)

6.1 OneToOne-Beziehung

Beispiel:

Entitäten:

  • User
  • Profile

User.php

/**
 * @ORM\OneToOne(targetEntity=Profile::class, cascade={"persist", "remove"})
 * @ORM\JoinColumn(nullable=false)
 */
private $profile;

Profile.php

/**
 * @ORM\OneToOne(targetEntity=User::class, inversedBy="profile")
 * @ORM\JoinColumn(nullable=false)
 */
private $user;

6.2 OneToMany und ManyToOne-Beziehungen

Beispiel:

Entitäten:

  • Category
  • Product

Category.php

/**
 * @ORM\OneToMany(targetEntity=Product::class, mappedBy="category")
 */
private $products;

Product.php

/**
 * @ORM\ManyToOne(targetEntity=Category::class, inversedBy="products")
 * @ORM\JoinColumn(nullable=false)
 */
private $category;

6.3 ManyToMany-Beziehung

Beispiel:

Entitäten:

  • Product
  • Tag

Product.php

/**
 * @ORM\ManyToMany(targetEntity=Tag::class, inversedBy="products")
 * @ORM\JoinTable(name="product_tag")
 */
private $tags;

Tag.php

/**
 * @ORM\ManyToMany(targetEntity=Product::class, mappedBy="tags")
 */
private $products;

6.4 Arbeiten mit Beziehungen

Hinzufügen eines Produkts zu einer Kategorie:

$category = new Category();
$category->setName('Elektronik');

$product = new Product();
$product->setName('Smartphone');
$product->setPrice(699.99);
$product->setCategory($category);

$entityManager->persist($category);
$entityManager->persist($product);
$entityManager->flush();

Hinzufügen von Tags zu einem Produkt:

$tag1 = new Tag();
$tag1->setName('Neu');

$tag2 = new Tag();
$tag2->setName('Angebot');

$product->addTag($tag1);
$product->addTag($tag2);

$entityManager->persist($tag1);
$entityManager->persist($tag2);
$entityManager->persist($product);
$entityManager->flush();

7. Arbeiten mit Repositories

7.1 Was ist ein Repository?

Ein Repository ist eine Klasse, die spezielle Abfragefunktionen für eine Entität bereitstellt. Standardmäßig generiert Doctrine für jede Entität ein Repository.

7.2 Erstellen eines benutzerdefinierten Repositories

Beim Erstellen einer Entität können Sie angeben, dass ein Repository erstellt werden soll.

Beispiel:

php bin/console make:entity --regenerate

Wählen Sie die Entität und geben Sie den Repository-Namen an.

7.3 Verwendung des Repositories

Beispiel:

// 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 findExpensiveProducts($price)
    {
        return $this->createQueryBuilder('p')
            ->andWhere('p.price > :price')
            ->setParameter('price', $price)
            ->orderBy('p.price', 'DESC')
            ->getQuery()
            ->getResult();
    }
}

Verwendung im Controller:

public function expensiveProducts(ProductRepository $productRepository)
{
    $products = $productRepository->findExpensiveProducts(1000);

    // ...
}

7.4 Weitere Methoden des Repositories

  • find($id): Findet eine Entität anhand der ID.
  • findOneBy($criteria): Findet eine Entität anhand von Kriterien.
  • findBy($criteria): Findet mehrere Entitäten anhand von Kriterien.
  • findAll(): Gibt alle Entitäten zurück.

Zusammenfassung

Doctrine ORM integriert sich nahtlos in Symfony und ermöglicht eine effiziente und objektorientierte Arbeit mit Datenbanken. Durch das Verständnis der folgenden Schlüsselkonzepte können Sie leistungsfähige und skalierbare Anwendungen entwickeln:

  • Einrichtung von Doctrine: Installieren und Konfigurieren der Datenbankverbindung.
  • Entitäten und Mappings: Erstellen von PHP-Klassen, die Datenbanktabellen repräsentieren.
  • Migrationen: Verwalten von Datenbankschemata über Migrationen.
  • CRUD-Operationen: Durchführen von grundlegenden Datenbankoperationen.
  • Abfragen: Verwenden von DQL und Query Builder für komplexe Abfragen.
  • Beziehungen: Modellieren von Datenbankbeziehungen zwischen Entitäten.
  • Repositories: Kapseln von Abfragefunktionen für wiederverwendbaren Code.

Weiterführende Ressourcen

Databases and the Doctrine ORM

Doctrine Tutorial


CEO Image

Ali Ajjoub

info@ajjoub.com

Adresse 0049-15773651670

Adresse Jacob-winter-platz,1 01239 Dresden

Buchen Sie jetzt Ihren Termin für eine umfassende und individuelle Beratung.

Termin Buchen

Kontaktieren Sie uns

Lassen Sie uns K o n t a k t aufnehmen!