Ukážeme si, že Doctrine není jenom ORMko a kdy jít o vrstvu níž. Jak DQL naučit věci, které v základu neumí, ale vaše databáze ano. A pár dalších tipů, jak nemít z databáze úplně hloupé úložiště.
Ukážeme si, že Doctrine není jenom ORMko a kdy jít o vrstvu níž. Jak DQL naučit věci, které v základu neumí, ale vaše databáze ano. A pár dalších tipů, jak nemít z databáze úplně hloupé úložiště.
4.
Minimum využití databáze každého Doctrinisty
● Co za vás dělá Doctrine
○ indexy pro vazby a primární klíče
○ vzdálené klíče
● Co si musíte pohlídat sami
○ unique indexy
○ vlastní typy
5.
Indexy a vzdálené klíče
class User {
/**
* @ORMId()
* @ORMColumn(type="uuid")
*/
private $id;
class Order {
/**
* @ORMManyToOne(targetEntity=User::class)
* @ORMJoinColumn(nullable=false)
*/
private $user;
6.
Unique indexy
class User {
/**
* @ORMColumn(type="string", unique=true)
*/
private $email;
8.
Unique indexy: vkládání a race conditions
● Opravdu to potřebujete řešit?
○ >90% aplikacím stačí check přes repository před flushem
○ >90% aplikací nikdy nenaroste natolik, aby to byl skutečný problém
● Pokud to opravdu opravdu potřebujete řešit
○ kdyby/doctrine ... NonLockingUniqueInserter
○ ^ brzy i samostatně, jako kdyby/doctrine-nonlocking-unique-inserter
○ ^ Symfony friendly ❤
○ ^ sledujte issue kdyby/doctrine#238
9.
Vlastní datový typ
class UuidType extends Type {
const NAME = 'uuid';
function getName() { return self::NAME; }
function getSQLDeclaration(
array $fieldDeclaration, AbstractPlatform $platform);
function convertToPHPValue(
$value, AbstractPlatform $platform);
function convertToDatabaseValue(
$value, AbstractPlatform $platform);
Zdroj: ramsey/uuid-doctrine
10.
Vlastní datový typ: komentáře ve schématu
class SomethingBasedOnStringType extends StringType {
function requiresSQLCommentHint(
AbstractPlatform $platform) : bool
// …
$platform->markDoctrineTypeCommented(Type::getType($type));
11.
Vlastní datový typ: konverze na úrovni DB
class GeometryType extends Type {
function canRequireSQLConversion() : bool;
function convertToDatabaseValueSQL(
$sqlExpr, AbstractPlatform $platform);
function convertToPHPValueSQL(
$sqlExpr, $platform);
16.
Batch operace s DQL
“UPDATE/DELETE statements are ported directly into a Database statement and
therefore bypass any locking scheme, events and do not increment the
version column. Entities that are already loaded into the persistence context will
NOT be synced with the updated database state. It is recommended to call
EntityManager#clear() and retrieve new instances of any affected entity.”
~ Dokumentace
17.
Batch operace s DQL
● Zkuste nejprve chytřejší způsoby iterace nad výsledkem
○ ORMQuery::iterate();
○ Stránkování
● Raději DQL update, než SQL update
● Neumí JOINy :(
22.
Rozšiřování DQL
● TreeWalker - může modifikovat AST
● output SqlWalker - generuje samotný SQL dotaz
● vlastní funkce
23.
Rozšiřování DQL: limitace
● Gramatika je jasně definovaná, není možné to nijak ohackovat
● Tree Walker může modifikovat výsledné AST, ale opět nezmění gramatiku
● SqlWalker to nemá jak zachránit
24.
Rozšiřování DQL: co jde
Kam nemůže DQL
SELECT order.finishedTime IS NULL AS something
FROM ...;
Tam musí funkce
SELECT IS_NULL(order.finishedTime) AS something
FROM ...;
25.
Rozšiřování DQL: vlastní funkce
class IsNull extends FunctionNode {
private $expression;
public function getSql(SqlWalker $sqlWalker) {
return $sqlWalker->walkArithmeticPrimary($this->expression) . ' IS NULL';
}
public function parse(Parser $parser) {
$parser->match(Lexer::T_IDENTIFIER);
$parser->match(Lexer::T_OPEN_PARENTHESIS);
$this->expression = $parser->ArithmeticPrimary();
$parser->match(Lexer::T_CLOSE_PARENTHESIS);
}
26.
SELECT employee,
AVG(salary) OVER (PARTITION BY employee.department) AS avgSalary
FROM MyEmployee employee;
SELECT employee,
WINDOW_OVER(AVG(salary), employee.department) AS avgSalary
FROM MyEmployee employee;
SELECT employee,
WINDOW(AVG(salary) OVER (PARTITION BY employee.department)) AS avgSalary
FROM MyEmployee employee;
Rozšiřování DQL: komplexnější syntaxe
31.
Shrnutí: co si z toho odnést?
● Logika v modelu dokud to jenom trochu jde
● Nebát se využívat hojně vlastní typy
● Rozšiřování DQL je snadné
● Doctrine není určená na batch operace
Kam dál?
● Youtube kanál “Nette Framework” > search “Doctrine”
Il semblerait que vous ayez déjà ajouté cette diapositive à .
Créer un clipboard
Vous avez clippé votre première diapositive !
En clippant ainsi les diapos qui vous intéressent, vous pourrez les revoir plus tard. Personnalisez le nom d’un clipboard pour mettre de côté vos diapositives.
Créer un clipboard
Partager ce SlideShare
Vous avez les pubs en horreur?
Obtenez SlideShare sans publicité
Bénéficiez d'un accès à des millions de présentations, documents, e-books, de livres audio, de magazines et bien plus encore, sans la moindre publicité.
Offre spéciale pour les lecteurs de SlideShare
Juste pour vous: Essai GRATUIT de 60 jours dans la plus grande bibliothèque numérique du monde.
La famille SlideShare vient de s'agrandir. Profitez de l'accès à des millions de livres numériques, livres audio, magazines et bien plus encore sur Scribd.
Apparemment, vous utilisez un bloqueur de publicités qui est en cours d'exécution. En ajoutant SlideShare à la liste blanche de votre bloqueur de publicités, vous soutenez notre communauté de créateurs de contenu.
Vous détestez les publicités?
Nous avons mis à jour notre politique de confidentialité.
Nous avons mis à jour notre politique de confidentialité pour nous conformer à l'évolution des réglementations mondiales en matière de confidentialité et pour vous informer de la manière dont nous utilisons vos données de façon limitée.
Vous pouvez consulter les détails ci-dessous. En cliquant sur Accepter, vous acceptez la politique de confidentialité mise à jour.