Pro Yearly is on sale from $80 to $50! »

Extbase: Alternativen zu "findAll"

1e3f36cacc64d0a924cdbb3fdc59e8af?s=47 move:elevator
September 14, 2019

Extbase: Alternativen zu "findAll"

Im Rahmen des TYPO3 Camps München hat Jan Männig einige Alternativen aufgezeigt, um in TYPO3 größere Datenmengen auslesen zu können.

1e3f36cacc64d0a924cdbb3fdc59e8af?s=128

move:elevator

September 14, 2019
Tweet

Transcript

  1. None
  2. Alternative zu „findAll“

  3. Jan Männig Senior Systems-Developer jma@move-elevator.de @janmaennig

  4. Agenda • Extbase mit 
 „Imageproblem“ Problemstellung Alternativen • MySql-View

    • Doctrine • Eigenes Model für Liste • Eigene DB-Abfrage Weiterführend • Caching Framework • Lazy Loading
  5. Kenne deinen Werkzeugkoffer …

  6. Problemstellung

  7. Extbase mit schlechtem Image • Vor allem das Datenhandling ist

    als unperformant verschrien Problemstellung
  8. Propertymapping als „Performancekiller“ • Mapping von Unterobjekten sehr zeitaufwändig Ursprung

  9. Alternativer Zugriff auf Daten

  10. MySql-View

  11. Alternativen MySql-View für Listen-Datensatz • MySql-View führt Daten aus mehreren

    Tabellen zusammen • Ergebnis ist eine Virtuelle Tabelle • Nutzbar wie normale Tabellen
  12. Alternativen MySql-View für Listen-Datensatz Controller tx_mebigdataexample_domain_model_booklist - B.uid - B.pid

    - B.title - B.description - R.uid AS ref_uid - F.identifier AS file_id
 sys_file_refenrence AS R
 - uid sys_file AS F
 - identifier
 tx_mebigdataexample_domain_model_book AS B
 - uid
 - title
 - description
 - …
  13. MySql-View für Listen-Datensatz # # Table structure for table 'tx_mebigdataexample_domain_model_booklist'

    # CREATE VIEW tx_mebigdataexample_domain_model_booklist AS SELECT b.uid, b.pid, b.title, b.description, sys_file_reference.uid as ref_uid, sys_file.identifier as file_id FROM tx_mebigdataexample_domain_model_book as b INNER JOIN sys_file_reference ON b.uid = sys_file_reference.uid_foreign INNER JOIN sys_file ON sys_file_reference.uid_local = sys_file.uid WHERE sys_file_reference.tablenames = 'tx_mebigdataexample_domain_model_book' group by b.uid order by b.sorting, sys_file_reference.sorting_foreign Anlage des Views
  14. MySql-View für Listen-Datensatz Wildcard für Haupttabelle • automatisiert alle Spalten

    der Ursprungstabelle 
 integriert • „images“ Spalte mit Anzahl der Bilder
  15. MySql-View für Listen-Datensatz # # Table structure for table 'tx_mebigdataexample_domain_model_booklist'

    # CREATE VIEW tx_mebigdataexample_domain_model_booklist AS SELECT b.*, sys_file_reference.uid as ref_uid, sys_file.identifier as file_id FROM tx_mebigdataexample_domain_model_book as b INNER JOIN sys_file_reference ON b.uid = sys_file_reference.uid_foreign INNER JOIN sys_file ON sys_file_reference.uid_local = sys_file.uid WHERE sys_file_reference.tablenames = 'tx_mebigdataexample_domain_model_book' group by b.uid order by b.sorting, sys_file_reference.sorting_foreign Anlage des Views mit allen Spalten der Haupttabelle
  16. MySql-View für Listen-Datensatz /** * Extract of the MySQL view

    repository */ class BooklistRepository extends Repository { private const ALLOWED_METHOD_PREFIX = 'find'; public function __call($methodName, $arguments) { if (self::ALLOWED_METHOD_PREFIX !== substr($methodName, 0, 4)) { throw new \BadMethodCallException( sprintf( 'You called method "%s". Only find methods are allowed!', $methodName ) ); } parent::__call($methodName, $arguments); } } Auszug aus dem Repository
  17. MySql-View für Listen-Datensatz # # Property mapping for single record

    # config.tx_extbase{ persistence{ classes{ MoveElevator\MeBigdataExample\Domain\Model\Booklist { mapping { tableName = tx_mebigdataexample_domain_model_booklist columns { title.mapOnProperty = title description.mapOnProperty = description ref_uid.mapOnProperty = imageReferenceId pages.mapOnProperty = pages file_id.mapOnProperty = imagePath } } } } } } Konfiguration des Mappings
  18. Doctrine

  19. Doctrine Doctrine • Datenbankabstraktionsschicht seit TYPO3 Version 8/9 integriert •

    Nutzung komplett unabhängig von der Repository-Struktur die Extbase bietet • Einsatz des QueryBuilders • Unabhängig vom jeweiligen Datenbank-System • Ergebnisse kommen als einfache Arrays zurück
  20. Doctrine /** * @param ObjectManager $objectManager */ public function __construct(ObjectManager

    $objectManager) { $this->queryBuilder = $objectManager->get(ConnectionPool::class) ->getQueryBuilderForTable(self::TABLE_NAME); } Initialisierung des „Query Builders“
  21. Doctrine public function findAll(): array { return $this->queryBuilder ->select('book.*', 'file.identifier

    as file_id') ->from(self::TABLE_NAME, 'book') ->innerJoin( 'book', 'sys_file_reference', 'ref', $this->queryBuilder->expr()->eq( 'ref.uid_foreign', $this->queryBuilder->quoteIdentifier('book.uid') ) ) ->innerJoin( 'ref', 'sys_file', 'file', $this->queryBuilder->expr()->eq( 'ref.uid_local', $this->queryBuilder->quoteIdentifier('file.uid') ) ) Zugriff auf Daten per Select (1/2)
  22. Alternativen ->where($this->queryBuilder->expr()->eq('book.deleted', 0)) ->andWhere( $this->queryBuilder->expr()->eq( 'ref.tablenames', $this->queryBuilder->quote(‚tx_mebigdataexample_domain_model_book‘) ) ) ->orderBy('sorting',

    'DESC')->addOrderBy('book.title') ->groupBy('book.uid') ->execute() ->fetchAll(); } Zugriff auf Daten per Select (2/2)
  23. Doctrine Ggf. Nachteile • Keine Objektstruktur -> in den meisten

    Anwendungsfällen aber auch nicht notwendig
  24. List-Model

  25. Alternativen List-Model • Eigenes Model für Listen und Filteransichten •

    Weniger Abhängigkeiten bzw. Verzweigungen in der Objekt- Struktur • Beschränkung auf alle Informationen die in der Ansicht notwendig sind
  26. List-Model class BookListEntry extends AbstractEntity { /** * @var string

    */ protected $title; /** * @var string */ protected $description; /** * @var int */ protected $pages; /** * Following setter and getter * … */ } Auszug aus Model
  27. List-Model use TYPO3\CMS\Extbase\Persistence\Repository; use TYPO3\CMS\Extbase\Persistence\Generic\Typo3QuerySettings; /** * Repository for list

    entry */ class BookListEntryRepository extends Repository { public function initializeObject() { /** @var $querySettings Typo3QuerySettings */ $querySettings = $this->objectManager>get(Typo3QuerySettings::class); $querySettings->setLanguageMode('strict')->setRespectStoragePage(false); $this->setDefaultQuerySettings($querySettings); } } Auszug aus Repository
  28. List-Model config.tx_extbase{ persistence{ classes{ MoveElevator\MeBigdataExample\Domain\Model\BookListEntry { mapping { tableName =

    tx_mebigdataexample_domain_model_book columns { title.mapOnProperty = title description.mapOnProperty = description pages.mapOnProperty = pages } } } } } } Konfiguration des Mappings
  29. Weiterführende Werkzeuge

  30. Caching Framework

  31. Caching Framework • Seit TYPO3 4.3 beinhaltet der Core ein

    Caching Framework • Ermöglicht die einfache Umsetzung verschiedener Cache- Strategien • Unabhängig vom Page-Cache Weiterführende Werkzeuge
  32. Caching Framework • Cache-Systeme Memcached, Database, Redis, … • Key/Value

    Zuweisung zwischen Cache-Identifikator und Wert • Weiterhin Tags und Lifetime als Parameter konfigurierbar Weiterführende Werkzeuge
  33. Caching Framework protected function getCachedMagic() { $cacheIdentifier = $this->calculateCacheIdentifier(); $cache

    = GeneralUtility::makeInstance( \TYPO3\CMS\Core\Cache\CacheManager::class )->getCache('myext_mycache'); // If $entry is null, it hasn't been cached. Calculate the value and store it: if (($entry = $cache->get($cacheIdentifier)) === FALSE) { $entry = $this->calculateMagic(); // [calculate lifetime and assigned tags] // Save value in cache $cache->set($cacheIdentifier, $entry, $tags, $lifetime); } return $entry; } Einfacher Zugriff auf den Cache
  34. Caching Framework /** * @param array $requestArguments * * @return

    string */ protected function calculateCacheIdentifier(array $requestArguments): string { $requestJson = json_encode($requestArguments); return md5($requestJson); } Generierung des „Cache Identifier“
  35. Generierung des „Cache Identifier“ • Um „Cache Flooding“ zu vermeiden,

    sollten zur Generierung des Identifiers nur die Parameter hinzugezogen werden, die Einfluss auf den Inhalt des Cache-Eintrags haben Caching Framework
  36. Lazy Loading

  37. Lazy Loading • Kein Vorausladen von abhängigen Unterobjekten • Ermittlung

    der Daten erst bei Bedarf Weiterführende Werkzeuge
  38. Lazy Loading class Book extends AbstractEntity { /** * @var

    string */ protected $title; /** * @var string */ protected $description; /** * @var \TYPO3\CMS\Extbase\Persistence\ObjectStorage<\TYPO3\CMS\Extbase\…> * @lazy */ protected $images; Notierung im Model
  39. TYPO3 Query Builder: https://docs.typo3.org/m/typo3/reference- coreapi/master/en-us/ApiOverview/Database/QueryBuilder/ Index.html?highlight=doctrine MySql-Views: http://www.mysqltutorial.org/mysql-views- tutorial.aspx#targetText=MySQL%20allows%20you%20to%20create, not%20refer%20to%20any%20table.

    Caching Framework: https://docs.typo3.org/m/typo3/reference- coreapi/master/en-us/ApiOverview/CachingFramework/Index.html Weiterführende Links
  40. Fragen?

  41. Infos: https://www.clickstorm.de/blog/doctrine-dbal-typo3-version-8/ https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/ ApiOverview/CachingFramework/Index.html Bilder: ! Quellen

  42. Danke für eure Aufmerksamkeit!