giovedì 7 agosto 2008

JAVA DAO, ORM, POJO

Abbiamo deciso di approfondire lo studio di Hibernate, effettivamente potrebbe esserci molto di aiuto, sia per la normale interrogazione di database (sia in selezione che in salvataggio) sia perché potrebbe evitarci i problemi di compatibilità con i due database che vogliamo supportare: Oracle e SQL Server.

Abbiamo deciso di non affidarci totalmente a GORM (Grails Object Relational Mapping) perchè groovy si rileva meno performante in alcune condizioni, e abbiamo paura che sia limitante nel futuro.

Quindi la scelta ricade sulla creazione di un ORM tramite JAVA DAO (Java Data Access Object) create con delle classi java POJO (Plain Old Java OBject).
Questo significa mappare tutto il nostro database con delle semplici classi java che devvano rispecchiare determinate carrateristiche.
In particolare Hibernate non ha richieste eccessive, ma secondo la logica del convention over configuration, è sempre meglio cercare di rispettare più richieste possibili, tra le quali:

  • Ogni classe dovrebbe avere un suo identificare univoco, chiamato Id (e qui per noi è un problema... perchè in pratica ogni tabella del nostro database ha un id composto da due campi stringa... decisamente lontano dagli standard che prevedono un id numerico autoincrementale... lo so lo so)
  • Ogni classe dovrebbe prevedere un costruttore a zero argomenti, che sarà utilizzato da Hibernate per istanziare la classe
  • Tutti i campi della tabella dovrebbero essere trasformari in campi della classe. Quindi ogni classe dovrebbe avere una serie di campi da considerare persistenti (quindi direttamente mappabilis ul database), preferibilmente da settare come privati, e quindi definire i getter e i setter per ognuno di questi campi. In particolare ogni campo dopvra rispettare le classiche convenzioni ORM, quindi nel caso di un nome campo (o tabella) composto d apiù nomi uniti con l'underscore, si dovrà converire con nome univoco con le lettere maiuscole per ogni parola che lo compone... esempio il campo data_di_nascita sarà convertito in dataDiNascita. Inoltre per convenzione Hibernate si aspetta di trovare i getter e i setter così composti getDataDiNascita e setDataDiNascita.
  • Le classi non dovrebbero essere dichiarate final, o in tal caso caso, dovrebbero implementare un interfaccia che dichiara tutti i metodi pubblici.
  • Nel caso di id composti conviene dichiarare l'id della classe come istanza di un'altra classe, convenzionamente chiamata nomeclasseId, nella quale vengono specificati i singoli campi delal chiave primaria composta.

Ci siamo affidati, per la stesura di queste classid i dominio, ad Hibernate Tool, un plugin per Eclipse appositamente studiato dallo staff di hibernate.
Seguendo i consigli di questa pagina, abbiamo proceduto con questi passi
  • dopo aver installato il plugin per eclipse (semplicemente scompattato lo zip preso dalla pagina di cui supra), ho creato un progetto grails, vuoto, con la classica procedura (nuova directory, grails create-app)
  • Ho messo nella cartella lib del progetto il jar con il driver jdbs del database sqlserver (jtds-1.2.2.jar preso su sourceforge). Avviato eclipse ho importato il progetto appena creato.
  • tasto destro sul progetto, ho creato un nuovo file di configurazione per hibernate: File -> New -> Other -> Hibernate -> Hibernate Configuration File.
    Il file di configurazione l'ho salvato nella directory grails-app/config/hibernate
    Come dialect ho scelto SQL Server, che poi sarà salvato nel file come org.hibernate.dialect.SQLServerDialect
    Come classe del driver ho scelto net.sourceforge.jtds.jdbc.Driver
    Come connection url jdbc:jtds:sqlserver://localhost/Sacci_Gabry;instance=SQLEXPRESS (ho instalato il database in locale)
    Il resto ho lasciato in bianco
  • ancora tasto destro e quindi ho settato al configuarazione della console di Hibernate (File -> New -> Other -> Hibernate -> Hibernate Console Configuration)
    Ho lasciato tutto come proposto, inserendo però nel classpath la lib inserita prima nella directory lib del progetto (il driver jdbc)
  • ancora tasto destro e quindi ho creato un file per il reverse enginering (di fatto quello che poi creerà i file) [File -> New -> Other -> Hibernate -> Hibernate Reverse Engineering File(reveng.xml) ]
    Il file l'ho inserito come prima in grails-app/config/hibernate
    dopo aver selezionato la configurazione e aspettato che il database venisse letto, ho selezionato solo le tabelle del dbo
  • Fatto questo ho fatto partire la compilazione (Lunch -> Hibernate Code Generation -> Open Hibernate Code Generation Dialog)
    Come outpout folder ho scelto src\java, e come nome di package gorm
    Come exporter ho selezionato le domain code, hibernate xml mappings, hibernate xml configuration, e lo Schema Documentation (decisamente opzionale, ma carino, genera della documentazione html interessante e facile da consultae)
    La generazione del codice impiega un po' ad eseguirsi.
  • A questo punto bisogna spostare qualche file per seguire le convenzioni hibernate/grails
    Il file hibernate.cfg.xml appena generato, diverso dal precedente in quanto conteiene tutti i riferimenti ai file di maping, va spostato nella directori config/hibernate, sovrascrivendo quindi il precedente
    Tutti i file hbl.xml vanno spostati nella stessa directorty grails-app/config/hibernate
A questo punto tutto è pronto per lavorare... si possono visualizzare e quindi utilizzare le view di eclipse predisposte per hibernate, consultare il database, la session factory, fare query HQL ecc..

Nessun commento: