Doctrine 2

Práce s hromadou dat

Jsem Tomáš :)

programátor

školitel

rodič

 

Apicart

Co náš čeká?

  • Doctrine DBAL
    • Hromadné výběry
  • Doctrine ORM
    • Hromadné výběry
    • Hromadné vkládání
    • Hromadné aktualizace

Kdo zná Doctrine?

Kdo používá Doctrine?

Doctrine DBAL

Hromadný výběr na úrovni SQL

Úkol č.1

Vygenerovat XML obsahující všechny produkty

Databáze:

Aplikace:

/** @var \Doctrine\DBAL\Connection $connection */
$connection = $this->connection;
$products = $connection->fetchAll('SELECT * FROM products ORDER BY id ASC');
foreach ($products as $product) {
    echo sprintf(
        '
            <product>
                <id>%d</id>
                <name>%s</name>
                <price>%d</price>
            </product>
        ',
        $product['id'],
        $product['name'],
        $product['price'],
    );
}

Výhody:

  • Rychle naprogramované
  • Snadno čitelné
  • Přehledné a intuitivní

Nevýhody:

  • Vykonání trvá dlouho
  • Běh je náročný na paměť

Databáze:

Aplikace:

$statement = $connection->prepare(
    'SELECT * FROM products ORDER BY id ASC',
    [\PDO::ATTR_CURSOR => \PDO::CURSOR_SCROLL]
);
$statement->execute();
while ($product = $statement->fetch(\PDO::FETCH_ASSOC)) {
    echo sprintf(
        '
            <product>
                <id>%d</id>
                <name>%s</name>
                <price>%d</price>
            </product>
        ',
        $product['id'],
        $product['name'],
        $product['price'],
    );
}

Výhody:

  • Rychle naprogramované
  • Vykonání je násobně rychlejší
  • Běh potřebuje minimum paměti

Nevýhody (subjektivní):

  • Obtížněji čitelné
  • Méně přehledné

Doctrine ORM

Hromadná práce na úrovni entit

Úkol č.2

Vygenerovat XML obsahující všechny produkty

Databáze:

Aplikace:

/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;
$query = $entityManager->createQuery(
    'SELECT p FROM App\Model\Entity\Product p ORDER BY p.id'
);
$products = $query->getArrayResult();
foreach ($products as $product) {
    echo sprintf(
        '
            <product>
                <id>%d</id>
                <name>%s</name>
                <price>%d</price>
            </product>
        ',
        $product->getId(),
        $product->getName(),
        $product->getPrice(),
    );
}

Výhody:

  • Snadno čitelné
  • Rychle naprogramované
  • Přehledné a intuitivní
  • Funguje i s přednačítání kolekcemi

Nevýhody:

  • Vykonání trvá dlouho
  • Běh je náročný na paměť

Databáze:

Aplikace:

/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;
$query = $entityManager->createQuery(
    'SELECT p from App\Model\Entity\Product p ORDER BY p.id'
);
$iterableResult = $query->iterate();
foreach ($iterableResult as $product) {
    echo sprintf(
        '
            <product>
                <id>%d</id>
                <name>%s</name>
                <price>%d</price>
            </product>
        ',
        $product[0]->getId(),
        $product[0]->getName(),
        $product[0]->getPrice(),
    );
    $entityManager->detach($product[0]);
}

Výhody:

  • Snadno čitelné
  • Rychle naprogramované
  • Přehledné a intuitivní
  • Vykonání je násobně rychlejší
  • Běh potřebuje minimum paměti

Nevýhody:

  • Nepodporuje přednačítání kolekcí

Úkol č.3

Naimportovat produkty od dodavatele do databáze

Aplikace:

$xml = [ // produkty načtené z našeho XML
    [
        'id' => 1,
        'name' => 'NATURVITA Biosil Plus 60 tablet',
        'price' => 58
    ],
    [
        //...
    ]
];

/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;

foreach ($xml as $data) {
    $product = new \App\Model\Entity\Product;
    $product->setId($data['id']);
    $product->setName($data['name']);
    $product->setPrice($data['price']);

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

Výhody:

  • Snadno čitelné
  • Rychle naprogramované
  • Přehledné a intuitivní

Nevýhody:

  • Vykonání trvá dlouho
  • Běh je náročný na paměť

Aplikace:

/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;
$xml = [ // produkty načtené z našeho XML
    [
        'id' => 1,
        'name' => 'NATURVITA Biosil Plus 60 tablet',
        'price' => 58
    ],
    [
        //...
    ]
];
$batchSize = 100;

foreach ($xml as $index => $data) {
    $product = new \App\Model\Entity\Product;
    $product->setId($data['id']);
    $product->setName($data['name']);
    $product->setPrice($data['price']);

    $entityManager->persist($product);

    if (($index % $batchSize) === 0) {
        $entityManager->flush();
    }

    $entityManager->flush();
}
/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;
$xml = [ // produkty načtené z našeho XML
    [
        'id' => 1,
        'name' => 'NATURVITA Biosil Plus 60 tablet',
        'price' => 58
    ],
    [
        //...
    ]
];
$batchSize = 100;

foreach ($xml as $index => $data) {
    $product = new \App\Model\Entity\Product;
    $product->setId($data['id']);
    $product->setName($data['name']);
    $product->setPrice($data['price']);

    $entityManager->persist($product);

    if (($index % $batchSize) === 0) {
        $entityManager->flush();
        $entityManager->clear();
    }

    $entityManager->flush();
    $entityManager->clear();
}

Výhody:

  • Snadno čitelné
  • Rychle naprogramované
  • Přehledné a intuitivní
  • Vykonání je násobně rychlejší
  • Běh je šetrnější na paměť

Nevýhody:

  • Je potřeba znovu načítat společné entity 

Úkol č.4

Zdražit všechny produkty o 10%

Aplikace:

/** @var \Doctrine\ORM\EntityManager $entityManager */
$entityManager = $this->entityManager;
$query = $entityManager->createQuery(
    'SELECT p from App\Model\Entity\Product p ORDER BY p.id'
);
$iterableResult = $query->iterate();
$batchSize = 100;
$i = 0;
foreach ($iterableResult as $row) {
    $product = $row[0];
    $product->increasePrice(10);

    if (($i % $batchSize) === 0) {
        $entityManager->flush();
        $entityManager->clear();
    }
    ++$i;
}

$entityManager->flush();

Výhody:

  • Snadno čitelné
  • Rychle naprogramované
  • Přehledné a intuitivní
  • Vykonání je násobně rychlejší
  • Běh je šetrnější na paměť

Nevýhody:

  • mnohonásobně pomalejší než SQL UPDATE 

Co si z toho odnést?

  • Ke stejnému cíli vede více cest
  • Krásný kód není vždy ten nejvýkonnější
  • Vyplatí se podívat do dokumentace
  • Myslete dopředu na objem dat
  • Zametejte stopy za  sebou
  • Vše měřit, monitorovat a optimalizovat

Díky za pozornost!

Nějaké otázky?

 

tomaspilar.cz  |        @tomaspilaru

Hromadná práce s daty v Doctrine

By tomaspilar

Hromadná práce s daty v Doctrine

  • 692