Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Livres Delphi Discussion :

"Introducing Delphi ORM" de John Kouraklis


Sujet :

Livres Delphi

  1. #1
    Membre éprouvé
    "Introducing Delphi ORM" de John Kouraklis
    Si comme moi vous êtes largués avec les composants Aurelius et l'ORM et n'avez pas encore lu la doc fournie par TMS Software, ce livre devrait rattraper le coup.



    Le but de l'auteur est de nous expliquer les concepts qui se cachent derrière l'ORM et de nous donner des cas pratiques d'utilisation avec Delphi et les composants de TMS Software.

    Pour en savoir plus il vous suffit de consulter le site de l'éditeur sur https://www.apress.com/gp/book/9781484250129

    Il est disponible à l'achat en numérique et "vrai" livre chez Amazon et en commande chez les librairies proches de chez vous que je vous encourage à solliciter si vous n'êtes pas à 24 heures près.

    Et d'ailleurs c'est l'occasion pour partager votre expérience d'Aurelius, de l'ORM et bien entendu de ce que vous avez pensé de ce livre une fois lu.

  2. #2
    Expert éminent sénior
    Personnellement, autant je comprends l'ORM autant je ne pige pas grand chose à l'Anglais sans Google Translate

    Moi quoi voulait découvrir MORmot pour son double emploi ORM et Remotable
    Voici que TMS a aussi bossé sur un ORM

    Le code TMS en exemple est très intéressant
    Ils pousse le modèle relationnel en mode automatique, je l'avais fait en D7 pour ma SLTPersistence je n'ai pas retenté l'aventure pour la SLTEntity en XE2 où j'ai triché en utilisant un Objet Query comme source des Entités me permettant d'écrire du SQL optimisé et d'avoir le confort de l'ORM ensuite (je l'utilise surtout pour les insertions et mise à jour, la lecture juste dans les écrans basiques, dès que l'on quitte un cadre simpliste du formulaire, un bon vieux SQL c'est plus rapide à écrire comme à exécuter )

    Code classique façon Query
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Query1.Sql.Text := 'SELECT I.ID AS INVOICE_ID, I.INVOICE_TYPE, I.INVOICE_NO, I.ISSUE_DATE, I.PRINT_DATE, ' +  
      'C.ID AS CUSTOMER_ID, C.CUSTOMER_NAME, C.SEX, C.BIRTHDAY, N.ID AS COUNTRY_ID, N.COUNTRY_NAME' +  
      'FROM INVOICE AS I INNER JOIN CUSTOMER AS C ON (C.ID = I.CUSTOMER_ID) ' +  
      'LEFT JOIN COUNTRY AS N ON (N.ID = C.COUNTRY_ID)' +  
      'WHERE I.ID = :INVOICE_ID;'  
    Query1.ParamByName('INVOICE_ID').AsInteger := 1;  
    Query1.Open;  
    ShowMessage(Format('Invoice No: %d, Customer: %s, Country: %s',  
      [Query1.FieldByName('INVOICE_NO').AsInteger,  
      Query1.FieldByName('CUSTOMER_NAME').AsString,  
      Query1.FieldByName('COUNTRY_NAME').AsString]));


    Code façon ORM Aurelius
    Il est très court grâce à la gestion du modèle relationnel en mode implicite

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    Invoice := Manager1.Find<TInvoice>(1);  
    ShowMessage(Format('Invoice No: %d, Customer: %s, Country: %s',  
      [Invoice.InvoiceNo, Invoice.Customer.Name, Invoice.Customer.Country.Name]));


    Selon l'ORM, la méthode de chargement est différente
    Dans certains, je pense à MyBatis pour Java, on peut fournir le SQL de chargement d'une Entity, il lance ainsi un SQL comme celui du premier bout de code même si l'on aurait pas utilisé le nom du client ou du Pays
    Dans d'autres, c'est généré automatiquement et l'accès à la DB est en Lazy Load, soit via une descritpion de la base via un XML ou via les MetaData obtenu depuis le SGBDR
    Avec les nouvelles RTTI, avec les Attributes cela doit être beaucoup plus élégant maintenant !
    Vu que le code contient .Customer.Country, je devine un générateur de code pour construire les objets métiers et leurs relations (l'ayant maintenu à la main dans ma couche D7, c'est nécessaire et l'outil de contrôle inverse que la BD n'a pas changé et pas le code )

    Selon les choix de TMS, le cas Lazy Load c'est
    .Find fait un SELECT uniquement sur INVOICE,
    le .Customer fait un SELECT sur CUSTOMER
    et le .Country fait un SELECT sur COUNTRY
    Tant que l'on accède pas à .Customer ou .Country cela ne récupère pas les données
    Cela ne fait plus que des SELECT Mono-table et j'ignore si au final 3 SELECT mono-table ce n'est pas plus couteux qu'un seul SELECT JOIN (avec les index/contraintes qu'il faut évidemment)

    le défaut étant que cela produit souvent une sorte de SELECT * car si TInvoice mappe tous les champs de la table, il doit tous les récupérer.
    Pour éviter cela dans mes ORM en jouant sur public/published on peut faire plusieurs objets métier qui mappe certaines colonnes, la logistique n'as pas besoin des même données que la compta par exemple.
    Comment TMS a optimisé cela ?
    A découvrir surement dans ce Livre


    le cas inverse où cela charge tout les relations dès le .Find, il est peu probable car un schéma un peu complexe de Base de Données et cela explose
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs