Ankündigung

Einklappen
Keine Ankündigung bisher.

Doctrine 2 Datensatz einfügen mit Nachschlagetabellen_id

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Doctrine 2 Datensatz einfügen mit Nachschlagetabellen_id

    Hallo zusammen,

    ich hoffe ich habe das rictige Unterforum gefunden. Ich habe ein Problem mit Docrine2 und dem Einfügen von Datensätzen wenn man dabei eine ID zu einer Nachschlagetabelle einfügen möchte. Worum geht es konkret:
    Ich habe in kleines Projekt zu Doctrine geschrieben um mich besser darin einarbeiten zu können. Dazu habe ich auf Basis des MVC eine kleine Webseite mit Formular gebaut wo man Bücher mit Preis und Währung abspeichern kann.

    Die Struktur ist wie folgt
    - mainverzeichnis
    --- index.php (controller)
    --- <vendor> <- da ist doctrine drin
    --- <views> <- die tpl Seiten Ausgabe und Formular
    ---<src>
    <Models> <- die Klassen


    Buch.php
    Preis.php
    Waehrung.php




    Nun die einzelnen Dateien

    index.php:
    PHP-Code:
    <?php

    require_once './src/Models/Buch.php';
    require_once 
    './src/Models/Preis.php';
    require_once 
    './src/Models/Waehrung.php';
    require_once 
    './inc/functions.inc.php';
    require_once 
    './inc/helper.inc.php';
    require_once 
    './inc/config.inc.php';

    use 
    Models\Buch;
    use 
    Models\Preis;
    use 
    Models\Waehrung;

    $action = isset($_REQUEST['action']) ? $_REQUEST['action'] : NULL;
    $view $action;

    switch (
    $action) {
      case 
    "lesen_single":
        
    // ein bestimmten Datensatz auslesen
        //$query = $em->createQuery("SELECT t FROM Models\Buch t WHERE t.id < 2");
        //$buchs = $query->getResult();

        
    $dql 'SELECT t FROM Models\Buch t WHERE t.id = :id';
        
    // Schritt 1: Vorbereiten
        
    $query $em->createQuery($dql);
        
    // Schritt 2: Befuellen
        
    $wert '1';
        
    $query->setParameter('id'$wert);
        
    // Schritt 3: Ausfuehren
        
    $buch $query->getResult();


        
    //$buchs = $em->getRepository('Models\Buch')->find(4);
        
    $view 'lesen';
        break;
        case 
    "lesen_join";


        
    //$dql = 'SELECT t FROM Models\Buch t';
        //
        //$dql = "SELECT a,b,w FROM Models\Preis a LEFT JOIN a.buch b LEFT JOIN a.waehrung w";
        
    $dql "SELECT b,p FROM Models\Buch b LEFT JOIN b.preis p";
        
    // Schritt 1: Vorbereiten
        
    $query $em->createQuery($dql);
        
    // Schritt 2: Befuellen

        // Schritt 3: Ausfuehren
        
    $preis $query->getResult();

        
    $view ='lesen_join';
        break;
        case 
    "lesen_all":
        
    //anweisungen was zu tun ist:
        // alle Datensätze auslesen

        
    $dql 'SELECT t FROM Models\Buch t';
        
    // Schritt 1: Vorbereiten
        
    $query $em->createQuery($dql);

        
    // Schritt 3: Ausfuehren
        
    $buch $query->getResult();

        
    $view 'lesen';
        break;
      case 
    "schreiben":
        break;
      case 
    "eintragen":    

        
    $data = array("preis" => $_POST['preis']);
        
    $preis = new Preis($data);

        
    $data_waehrung= array("waehrung" => "1");
        
    $waehrung= new Waehrung($data_waehrung);

        
    //$preis->setWaehrung($waehrung);
        
    $waehrung->addPreis($preis);
        
    $preis->setWaehrung($waehrung);

        
    $em->persist($preis);
        
    $em->flush();

        
    // Wir füllen die Setter der Tabelle Preis mit den echten Daten     
        
    $data2 = array("title" => $_POST['title']);     
        
    $buch = new Buch($data2);

        
    // Wir stellen die Relation von Tabelle Buch zu Tabelle Preis her
        
    $preis->addBuch($buch);
        
    $buch->setPreis($preis);
        
    $em->persist($buch);
        
    $em->flush();

        
    $view 'index';
        break;
        default:

        
    $view 'index';
        break;
    }
    require_once 
    'views/' $view '.tpl.php';
    und nun die viewsIch geb mal nur das Formular hier an, die andern Ausgaben sind ja ncih relevant.)
    HTML-Code:
    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="utf-8" />
        <title>Buch</title>
      </head>
      <body>
        <form method="post" action="index.php?action=eintragen">
          <label for="title">Titel:</label>
          <input type="text" name="title" value="" placeholder="Titel">
          <label for="preis">Preis:</label>
          <input type="text" name="preis" value="" placeholder="Preis">
          <input type="submit" name="submit" value="senden">
        </form>
      </body>
    </html>
    und nun die KLassen:

    PHP-Code:
    <?php

    namespace Models;

    use 
    Doctrine\ORM\Mapping as ORM;
    use 
    Webmasters\doctrine\ORM\Util;

    /**
     * @ORM\Entity
     * @ORM\Table(name="buch")
     */
    class Buch {

      
    /**
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       * @ORM\Column(type="integer")
       */
      
    private $id 0;

      
    /**
       * @ORM\Column(type="string", length=25, unique=true)
       */
      
    private $title '';

      
    /**
       * @ORM\ManyToOne(targetEntity="Preis", inversedBy="buch")
       */
      
    private $preis;

      function 
    __construct(array $data = array()) {
        
    Util\ArrayMapper::setEntity($this)->setData($data);
      }

      function 
    getId() {
        return 
    $this->id;
      }

      function 
    getTitle() {
        return 
    $this->title;
      }

      function 
    setTitle($title) {
        
    $this->title $title;
      }

      function 
    getPreis() {
        return 
    $this->preis;
      }

      function 
    setPreis($preis) {
        
    $this->preis $preis;
      }

      function 
    __toString() {
        
    $test = (string) $this->getId();
        return 
    $test;
      }

    }
    PHP-Code:
    <?php

    namespace Models;

    use 
    Doctrine\ORM\Mapping as ORM;
    use 
    Webmasters\doctrine\ORM\Util;

    /**
     * @ORM\Entity
     * @ORM\Table(name="preis")
     */
    class Preis {

      
    /**
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       * @ORM\Column(type="integer")
       */
      
    private $id 0;

      
    /**
       * @ORM\Column(type="decimal", precision=6, scale=2)
       */
      
    private $preis 0.00;

      
    /**
       * @ORM\OneToMany(targetEntity="Buch", mappedBy="preis")
       */
      
    private $bucher;

      
    /**
       * @ORM\ManyToOne(targetEntity="Waehrung", cascade={"all"}, fetch="LAZY")
       */
      
    private $waehrung;


      function 
    __construct(array $data = array()) {
        
    Util\ArrayMapper::setEntity($this)->setData($data);
        
    $this->bucher = new \Doctrine\Common\Collections\ArrayCollection();
        
    //$this->setData($data);
      
    }

      function 
    getId() {
        return 
    $this->id;
      }

      function 
    getPreis() {
        return 
    $this->preis;
      }

      function 
    setPreis($preis) {
        
    $this->preis $preis;
      }

      function 
    getBucher() {
        return 
    $this->bucher;
      }

      function 
    setBucher($buch) {
        
    $this->bucher $buch;
      }

      public function 
    clearBucher() {
        
    $this->bucher->clear();
      }

      public function 
    addBuch(Buch $buch) {
        
    $this->bucher->add($buch);
      }

      public function 
    hasBuch(Buch $buch) {
        return 
    $this->bucher->contains($buch);
      }

      public function 
    removeBuch(Buch $buch) {
        
    $this->bucher->removeElement($buch);
      }

      function 
    getWaehrung() {
        return 
    $this->waehrung;
      }

      function 
    setWaehrung($waehrung) {
        
    $this->waehrung $waehrung;
      }

      function 
    __toString() {
        return 
    $this->getTitle();
      }

    }
    PHP-Code:
    <?php

    namespace Models;

    use 
    Doctrine\ORM\Mapping as ORM;
    use 
    Webmasters\doctrine\ORM\Util;

    /**
     * @ORM\Entity
     * @ORM\Table(name="waehrung")
     */
    class Waehrung {

      
    /**
       * @ORM\Id
       * @ORM\GeneratedValue(strategy="AUTO")
       * @ORM\Column(type="integer")
       */
      
    private $id 0;

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

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

      
    /**
       * @ORM\OneToMany(targetEntity="Preis", mappedBy="waehrung")
       */
      
    private $preise 0.00;

      function 
    __construct(array $data = array()) {
        
    Util\ArrayMapper::setEntity($this)->setData($data);
        
    $this->preise = new \Doctrine\Common\Collections\ArrayCollection();

        
    //$this->setData($data);
      
    }

      function 
    getId() {
        return 
    $this->id;
      }

      function 
    setId($id) {
        
    $this->id $id;
      }

      function 
    getWaehrung() {
        return 
    $this->waehrung;
      }

      function 
    setWaehrung($waehrung) {
        
    $this->waehrung $waehrung;
      }

      function 
    getBeschreibung() {
        return 
    $this->beschreibung;
      }

      function 
    setBeschreibung($beschreibung) {
        
    $this->beschreibung $beschreibung;
      }

      function 
    getPreise() {
        return 
    $this->preise;
      }

      function 
    setPreise($preise) {
        
    $this->preise $preise;
      }

      public function 
    clearPreise() {
        
    $this->preise->clear();
      }

      public function 
    addPreis(Preis $preis) {
        
    $this->preise->add($preis);
      }

      public function 
    hasPreis(Preis $preis) {
        return 
    $this->preise->contains($preis);
      }

      public function 
    removePreis(Preis $preis) {
        
    $this->preise->removeElement($preis);
      }

      function 
    __toString() {
        return 
    $this->getBeschreibung();
      }

    }
    Code:
    --
    -- Tabellenstruktur für Tabelle `buch`
    --
    
    CREATE TABLE `buch` (
      `id` int(11) NOT NULL,
      `preis_id` int(11) DEFAULT NULL,
      `title` varchar(25) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- --------------------------------------------------------
    
    --
    -- Tabellenstruktur für Tabelle `preis`
    --
    
    CREATE TABLE `preis` (
      `id` int(11) NOT NULL,
      `waehrung_id` int(11) DEFAULT NULL,
      `preis` decimal(6,2) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    -- --------------------------------------------------------
    
    --
    -- Tabellenstruktur für Tabelle `waehrung`
    --
    
    CREATE TABLE `waehrung` (
      `id` int(11) NOT NULL,
      `waehrung` varchar(5) NOT NULL,
      `beschreibung` varchar(25) NOT NULL
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    --
    -- Daten für Tabelle `waehrung`
    --
    
    INSERT INTO `waehrung` (`id`, `waehrung`, `beschreibung`) VALUES
    (1, '€', 'Euro');
    So, hoffe alles hat richtig geklappt.
    Also mein Problem ist das er wenn ich den Datensatz speichern will er auch ein neuen Eintrag in der Tabelle "waehrung" macht, anstatt die ID welche ich ihm in dem Controller übergeben will zu benutzen und in der Tabelle "Preis" im Feld "waehrung_id" zeinzutragen.

    Ich jab nun etwas in der Doku gefunden zur Annotation von dem Feld in der Klasse Preis.
    PHP-Code:
    * @ORM\JoinColumn(name="waehrung_id"referencedColumnName="id"
    Allerdings find ich nichts dazu wie man die Gegenseite dann in der Annotation editieren soll. Muss man die dann überhaupt angeben? Und was ist mit den Methoden in Waehrung? Werden die dann noch gebraucht? Ich kann mi der Dokumentation leider so garnichs anfangen, bzw sie lässt mich mit mehr Fragen zurück als sie Antworten gibt. Hoffe mir kann hier wer helfen.

    bye
    Graysorn

  • #2
    So erstellst du natürlich immer einen neue Währung, statt den bestehenden Eintrag aus der Datenbank zu holen:


    $data_waehrung= array("waehrung" => "1");
    $waehrung= new Waehrung($data_waehrung);
    Stattdessen müsste es etwas sein wie:

    PHP-Code:
    $preis->setWaehrung($em->find(Waehrung::class, 1
    Und die Join Column immer mit angeben bei ManyToOne. Guckst du:
    https://www.doctrine-project.org/pro...n-mapping.html
    sorry, shift-taste kaputt

    Kommentar


    • #3
      Hi Meister1900,

      danke für die schnelle Hilfe. Jetzt klappt es. Nur zum Verständnis noch eine Frage: Doctrine hat erkannt das ich ein neues Objekt erstell hab und nicht ein Objekt (Datensatz) aus der Tabelle Waehrung geladen habe? Und hat deswegen immer ein Datensatz dazugetragen und dessen ID eingetragen ?

      Kommentar


      • #4
        So ist es...
        Die ganzen Abfragen musst du natürlich auch nicht mit DQL lösen. Das kannst du alles mit Find/FindBy machen
        sorry, shift-taste kaputt

        Kommentar

        Lädt...
        X