Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


repository_datenbank [2023.12.12 16:02] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Datenbank Funktionen des Repository ======
  
 +
 +Sinn des Repository in einer Extension ist es, Daten aus der Datenbank holen, schreiben oder bearbeiten.
 +Neben dem bisherigen QueryResultInterface gab es im Repository stets die Möglichkeit, Datenbanken direkt mit SQL-Code abzufragen. Dies ist mit der LTS 9 von TYPO3 nicht mehr möglich. Entsprechende Abfragen müssen umgeschrieben werden. Für den Fall des IBK Blogs habe ich diese exemplarisch durchgezogen. Der Aufwand lohnt sich, denn man erhält nicht nur bessere Fehlermeldungen bei Fehlern in der SQL-Syntax, der Code wird auch strukturierter und leichter durchschaubar.
 +
 +===== Das QueryInterface =====
 +
 +Über das QueryInterface werden Anfragen an die Datenbank gestellt.
 +
 +
 +==== Einfache Listenfunktion ====
 +
 +
 +  public function findAllBlogs()
 +  {
 +    $query = $this->createQuery();
 +    $result = $query->execute();
 +    return $result;
 +  }
 +  
 +  
 +==== Listenfunktion mit Sortierung ====
 +
 +  public function findOrderedBlogs()
 +  {
 +    $query = $this->createQuery();
 +    $query->setOrderings(array(
 +      'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
 +    ));
 +    $result = $query->execute();
 +    return $result;
 +  }
 +    
 +==== Listenfunktion mit Sortierung und Offset ====
 +
 +**Wichtige Parameter bei dieser Funktion:**
 +  * Übergabe von Parametern
 +  * Ordering nach Parameter
 +  * Offset nach Parameter
 +
 +  public function findBlogs($blogLimit, $blogOffset)
 +  {
 +    $query = $this->createQuery();
 +    $query->setOrderings(array(
 +      'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
 +    ));
 +    $query->setLimit(intval($blogLimit));
 +    $query->setOffset(intval($blogOffset));
 +    $result = $query->execute();
 +    return $result;
 +  }
 +  
 +==== Suche nach Text in einem Feld ====
 +
 +  /**
 +   * Find all posts with a distinct Kategorie
 +   
 +   * @param int $katid   UID for Kategorie
 +   * @param int $limit   How many posts should be found.
 +   * @param int $offset  Where the search should start
 +   * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
 +   */
 +  public function findByKategorie($katid, $limit, $offset)
 +  {
 +    $query = $this->createQuery();
 +    $query->matching($query->equals('kategorie', $katid));
 +    $query->setLimit(intval($limit));
 +    $query->setOffset(intval($offset));
 +    $query->setOrderings(array(
 +      'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
 +    ));
 +    $result = $query->execute();
 +    return $result;
 +  }
 +
 +==== Volltextsuche ====
 +
 +  /**
 +   * Find all posts with a title or content which contains the specified search word.
 +   
 +   * @param string $searchWord     Search word to look for.
 +   * @param int    $limit          How many posts should be found.
 +   * @param int    $offset         Where the search should start
 +   * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
 +   */
 +  public function findBySearch($searchWord, $limit, $offset)
 +  {
 +    $query = $this->createQuery();
 +    $query->matching(
 +      $query->logicalOr(
 +        $query->like('titel', '%' . $searchWord . '%'), 
 +        $query->like('kurzfassung', '%' . $searchWord . '%'), 
 +        $query->like('inhalt', '%' . $searchWord . '%')
 +      )
 +    );
 +    $query->setLimit(intval($limit));
 +    $query->setOffset(intval($offset));
 +    $query->setOrderings(array(
 +      'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
 +    ));
 +    $result = $query->execute();
 +    return $result;
 +  }
 +==== Zähler (Counter) integrieren ====
 +
 +
 +  public function getBlogKategorienCounter($katid)
 +  {
 +    $query = $this->createQuery();
 +    $query->matching($query->equals('kategorie', $katid));
 +    $result = $query->execute()->count();
 +    return $result;
 +  }
 +==== Ergebnisse sortieren ====
 +
 +**Sortierung in absteigender Reihenfolge:**
 +
 +  $query->setOrderings(array(
 +    'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING
 +  ));
 +  
 +**Sortierung in aufsteigender Reihenfolge:**
 +
 +  $query->setOrderings(array(
 +    'datum' => \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_ASCENDING
 +  ));  
 +===== Der ConnectionPool =====
 +
 +Ab der LTS 9 von TYPO3 werden SQL Anfragen an die Datenbank über diese Klasse gemacht.
 +
 +**Einbindung des ConnectionPool:**
 +
 +  <?php
 +  namespace Ibk\Ibkblog\Domain\Repository;
 +  
 +  use TYPO3\CMS\Core\Utility\GeneralUtility;
 +  use TYPO3\CMS\Core\Database\ConnectionPool;  
 +  
 +==== Name einer Kategorie auslesen ====
 +
 +
 +  public function getBlogKategorienName($katid)
 +  {
 +    $table = "tx_ibkblog_domain_model_kategorie";
 +    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
 +    $katNameArray = $queryBuilder ->select('name')
 +      ->from($table)
 +      ->where(
 +        $queryBuilder->expr()->eq('uid', $queryBuilder->createNamedParameter($katid, \PDO::PARAM_INT))
 +      )
 +      ->execute()
 +      ->fetchAll();
 +      
 +    $katName = $katNameArray['name'];
 +    return $katName;
 +  }
 +==== Mehrere Tabellen mit JOIN abfragen ====
 +
 +**Wichtige Elemente dieser Funktion:**
 +  * Kreuztabellenabfrage mit Join über zwei Felder
 +  * Ordering in aufsteigender Reihenfolge
 +  * Gruppierung von Ergebnissen
 +  * Zähler für gruppierte Ergebnisse
 +  * Volltextsuche mit auskommentierten "%" der SQL-Syntax
 +
 +  public function tagShow($pid)
 +  {
 +    $tagShowArray = [];
 +    $table = "tx_ibkblog_domain_model_tag";
 +    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
 +       
 +    $tagShowArray = $queryBuilder 
 +      ->select('tx_ibkblog_domain_model_tag.uid', 'tx_ibkblog_domain_model_tag.name')
 +      ->addSelectLiteral(
 +        $queryBuilder->expr()->count('tx_ibkblog_domain_model_tag.name', 'counter')
 +      )
 +      ->from('tx_ibkblog_domain_model_tag')
 +      ->join(
 +        'tx_ibkblog_domain_model_tag',
 +        'tx_ibkblog_blog_tag_mm',
 +        'tx_ibkblog_blog_tag_mm',
 +        $queryBuilder->expr()->eq(
 +          'tx_ibkblog_domain_model_tag.uid', 
 +          $queryBuilder->quoteIdentifier('tx_ibkblog_blog_tag_mm.uid_foreign')
 +        )
 +      )
 +      ->where(
 +        $queryBuilder->expr()->eq(
 +          'tx_ibkblog_domain_model_tag.pid', 
 +          $queryBuilder->createNamedParameter($pid, \PDO::PARAM_INT)
 +        )
 +      )
 +      ->orderBy('tx_ibkblog_domain_model_tag.name', 'ASC'           
 +      ->groupBy('tx_ibkblog_domain_model_tag.uid'           
 +      ->execute()
 +      ->fetchAll();
 +        
 +    return $tagShowArray;
 +  }
 +    
 +Wie man an diesem Beispiel sieht: Die Nutzung der **ConnectionPool** Klasse bringt einen sehr strukturierten Code mit sich, anhand dessen man Monate nach dem Schreiben der Abfrage recht schnell versteht, was diese Funktion leistet.
 +
 +==== Kreuztabellenabfrage über mehrere Felder ====
 +
 +Für die Bildergalerie auf der Georgienseite benötigen wir für eine Filterung nach Tags eine Kreuztabellenabfrage. Bilder und Tags stehen in einer n:m Beziehung zueinander. Entsprechend müssen die vorhandenen Tags und ihre Verknüpfung abgefragt werden.
 +
 +  $tagArray = [];
 +  $table = "tx_ibkbilder_domain_model_tag";
 +  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
 +
 +  $tagArray = $queryBuilder 
 +    ->select('tx_ibkbilder_domain_model_tag.tag', 
 +      'tx_ibkbilder_bilder_tag_mm.uid_local', 
 +      'tx_ibkbilder_bilder_tag_mm.uid_foreign', 
 +      'tx_ibkbilder_domain_model_bilder.uid', 
 +      'tx_ibkbilder_domain_model_bilder.bildergalerie')
 +    ->from('tx_ibkbilder_domain_model_tag')
 +    ->from('tx_ibkbilder_bilder_tag_mm')
 +    ->from('tx_ibkbilder_domain_model_bilder')
 +    ->where(
 +      $queryBuilder->expr()->eq(
 +        'tx_ibkbilder_bilder_tag_mm.uid_local', 
 +        $queryBuilder->quoteIdentifier('tx_ibkbilder_domain_model_bilder.uid')
 +      )
 +    )
 +    ->andWhere(
 +      $queryBuilder->expr()->eq(
 +        'tx_ibkbilder_domain_model_tag.uid', 
 +        $queryBuilder->quoteIdentifier('tx_ibkbilder_bilder_tag_mm.uid_foreign')
 +      )
 +    )
 +    ->andWhere(
 +      $queryBuilder->expr()->eq(
 +        'tx_ibkbilder_domain_model_bilder.bildergalerie', 
 +        $queryBuilder->createNamedParameter($bildergalerie, \PDO::PARAM_INT)
 +      )
 +    )
 +    ->orderBy('tx_ibkbilder_domain_model_tag.tag', 'ASC'           
 +    ->groupBy('tx_ibkbilder_domain_model_tag.tag'           
 +    ->execute()
 +    ->fetchAll();
 +
 +
 +==== Volltextsuche über mehrere Felder ====
 +  
 +  /**
 +   * Find number of all posts with a title or content which contains the specified search word.
 +   
 +   * @param string $searchWord Search word to look for.
 +   * @return \TYPO3\CMS\Extbase\Persistence\QueryResultInterface
 +   */
 +  public function findNumberBySearch($searchWord)
 +  {
 +    $table = "tx_ibkblog_domain_model_blog";
 +    $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table);
 +    $idArray = $queryBuilder ->select('uid')
 +      ->from($table)
 +      ->orWhere(
 +        $queryBuilder->expr()->like(
 +          'titel', 
 +          $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%')
 +        ),
 +        $queryBuilder->expr()->like(
 +          'kurzfassung', 
 +          $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%')
 +        ),
 +        $queryBuilder->expr()->like(
 +          'inhalt', 
 +          $queryBuilder->createNamedParameter('%' . $queryBuilder->escapeLikeWildcards($searchWord) . '%')
 +        )
 +      )
 +      ->execute()
 +      ->fetchAll();        
 +           
 +    return $idArray;
 +  }  
 + 
 +==== Neues Objekt im Blog speichern ====
 +
 +Bei dieser Funktion kommen mehrere Methoden des ConnectionPool zum Einsatz. Nach Stand September 2018 der TYPO3 Version 9 DEV sollen Verbindungen nicht wiederverwendet werden. Daher wird hier für jede Anfrage an die Datenbank eine neue Instanz des ConnectionPool initialisiert.
 +
 +  public function saveBlogKommentar($kommentar, $blog)
 +  {
 +    $message = 'Der Beitrag wurde gespeichert';
 +    $queryName = $kommentar->getName();
 +    $queryEmail = $kommentar->getEmail();
 +    $queryKommentar = $kommentar->getKommentar();
 +    $queryDatum = $kommentar->getDatum();
 +    $queryPid = $kommentar->getPid();
 +    $pos = strrpos($blog, ':') + 1;
 +    $queryBlog = intval(substr($blog, $pos));
 +    
 +    ## Kommentar zu einem Beitrag speichern
 +    $queryBuilder1 = GeneralUtility::makeInstance(ConnectionPool::class)
 +      ->getQueryBuilderForTable('tx_ibkblog_domain_model_kommentar');
 +    $save1 = $queryBuilder1
 +      ->insert('tx_ibkblog_domain_model_kommentar')
 +      ->values([
 +        'name' => $queryName, 
 +        'email' => $queryEmail, 
 +        'kommentar' => $queryKommentar, 
 +        'blog' => $queryBlog, 
 +        'datum' => $queryDatum, 
 +        'pid' => $queryPid,
 +      ])
 +      ->execute();
 +      
 +    ## Anzahl bisheriger Kommentare auslesen und um 1 erhöhen
 +    $queryBuilder2 = GeneralUtility::makeInstance(ConnectionPool::class)
 +      ->getQueryBuilderForTable('tx_ibkblog_domain_model_blog');        
 +    $save2 = $queryBuilder2 ->select('uid')
 +      ->from('tx_ibkblog_domain_model_blog')
 +      ->where(
 +        $queryBuilder2->expr()->eq('uid', $queryBuilder2->createNamedParameter($queryBlog, \PDO::PARAM_INT))
 +      )
 +      ->setMaxResults(1)
 +      ->execute()
 +      ->fetchAll();
 +        
 +    $queryBuilder3 = GeneralUtility::makeInstance(ConnectionPool::class)
 +      ->getQueryBuilderForTable('tx_ibkblog_domain_model_blog');                
 +    $kommentarnew = $save2['kommentar'] + 1;
 +      
 +    ## Neue Anzahl Kommentare in Blog Objekt speichern
 +    $save3 = $queryBuilder3 ->update('tx_ibkblog_domain_model_blog', 't')
 +      ->where(
 +        $queryBuilder3->expr()->eq('uid', $queryBuilder3->createNamedParameter($queryBlog, \PDO::PARAM_INT))
 +      )
 +      ->set('t.kommentar', $kommentarnew)
 +      ->execute();
 +    
 +    return $message;
 +  }
 +