$30 off During Our Annual Pro Sale. View Details »

Extbase: Alternativen zu "findAll"

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.

move:elevator

September 14, 2019
Tweet

More Decks by move:elevator

Other Decks in Programming

Transcript

  1. View Slide

  2. Alternative zu „findAll“

    View Slide

  3. Jan Männig
    Senior Systems-Developer
    [email protected]
    @janmaennig

    View Slide

  4. Agenda
    • Extbase mit 

    „Imageproblem“
    Problemstellung Alternativen
    • MySql-View
    • Doctrine
    • Eigenes Model für Liste
    • Eigene DB-Abfrage
    Weiterführend
    • Caching Framework
    • Lazy Loading

    View Slide

  5. Kenne deinen
    Werkzeugkoffer …

    View Slide

  6. Problemstellung

    View Slide

  7. Extbase mit schlechtem Image
    • Vor allem das Datenhandling ist als unperformant verschrien
    Problemstellung

    View Slide

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

    View Slide

  9. Alternativer Zugriff auf Daten

    View Slide

  10. MySql-View

    View Slide

  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

    View Slide

  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

    - …

    View Slide

  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

    View Slide

  14. MySql-View für Listen-Datensatz
    Wildcard für Haupttabelle
    • automatisiert alle Spalten der Ursprungstabelle 

    integriert
    • „images“ Spalte mit Anzahl der Bilder

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  18. Doctrine

    View Slide

  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

    View Slide

  20. Doctrine
    /**
    * @param ObjectManager $objectManager
    */
    public function __construct(ObjectManager $objectManager)
    {
    $this->queryBuilder = $objectManager->get(ConnectionPool::class)
    ->getQueryBuilderForTable(self::TABLE_NAME);
    }
    Initialisierung des „Query Builders“

    View Slide

  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)

    View Slide

  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)

    View Slide

  23. Doctrine
    Ggf. Nachteile
    • Keine Objektstruktur -> in den meisten Anwendungsfällen aber
    auch nicht notwendig

    View Slide

  24. List-Model

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  29. Weiterführende Werkzeuge

    View Slide

  30. Caching Framework

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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“

    View Slide

  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

    View Slide

  36. Lazy Loading

    View Slide

  37. Lazy Loading
    • Kein Vorausladen von abhängigen Unterobjekten
    • Ermittlung der Daten erst bei Bedarf
    Weiterführende Werkzeuge

    View Slide

  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

    View Slide

  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

    View Slide

  40. Fragen?

    View Slide

  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

    View Slide

  42. Danke für eure Aufmerksamkeit!

    View Slide