Gestione efficace dei database con PHP 5 (Parte VI)

Pagina 6 di 8

Struttura dei dati

Nelle applicazioni complesse non operiamo solamente sulletabelle nel DB, ma sull'insieme dei rapporti reciprocitra tabelle. Propel possiede meccanismi, che ci tolgono unaparte del carico di lavoro, relativo alla manutenzionemanuale delle dipendenze tra record nelle tabelle. Questecaratteristiche di Propel, le abbiamo già incontratenel Listing 2, dove il richiamo dei metodi$book->setPublisher($pub) ha provocato la trascrizionedell'oggetto editori e dell'oggetto libri con irelativi identificatori editori in una chiave esterna.

Per utilizzare il supporto di Propel nel servire larelazione, dovremo dapprima informarlo sui collegamenti trale singole tabelle. Così come le altre informazionisulla struttura fisica del DB, le relazioni verranno definitenel file XML. Per fare mente locale, guardiamo il Listing 6.

Listing 6. Definizione della relazioneuno-molti

 

<table name="book" description="Tabella libri">...<foreign-key foreignTable="publisher"><reference local="publisher_id" foreign="publisher_id"/></foreign-key>...</table>

 

 

Vediamo la trascrizione foreign-key, che nella classeBookPeer provocala generazione di diversi metodi aggiuntivi,tra cui.: BookPeer::getPublisher() eBookPeer::setPublisher($pub). Questi metodi operano suglioggetti interi, e non sui loro identificatori, quindi,sarà facilissimo leggere o modificarne i datirelativi.

Anche nella classe BaseBookPeer si trova un frammento dicodice interessante:BaseBookPeer::doSelectJoinPublisher(Criteria $c). Questometodo permette di richiedere quali libri soddisfanoilcriterio $c e contemporaneamente, di raccogliere i datidell'editore correlati ad un certo libro. Questo èun facile modo di costruire query rivolte agli oggetti inpiùdi una singola tabella.

A parte la relazione da uno a molti, nel progetto realeincontriamo anche collegamenti del tipo da molti a molti. Ilsistema di mappatura degli oggetti nella tabella adottato daPropel è un po' semplificato, affinché leclassi corrispondano quasi esattamente alle tabelle nel DB.Questa regola è trasmessa anche alle tabellecollegate. Purtroppo, Propel non maschera completamente ilfatto che esistono tabelle intermedie: queste vannoesplicitamente dichiarate nel file dello schema XML.

Le relazioni di diverso tipo non è l'uni-cadisposizione della struttura dati, che è supportata daPropel. Questa libreria offre anche un semplice supportoperla gerarchia dei settori e della struttura ad albero.

 

Ampliamento delle classi generate

Se guardiamo attentamente i file generati da118-propel-generator (Fig. 4 e 5), ci rendiamo conto che leclassi create nella cartella principale sono praticamentevuote, sono state ampliate solo le classi collocate nellasottocartella om. Questi scheletri sono appositamentepreparati per la modifica e l'ampliamento dellefunzionalità standard.

All'inizio osserviamo le classi di nome [NomeTabella], ades. Book. Viene ampliata dalla classe BaseBook econcet-tualmente corrisponde ai dati ed alle operazioni nelrecord unico della tabella nel DB. Questo è il luogoottimale, per aggiungere comportamenti specifici perl'og-getto businnes. Diciamo che, nel nostro negoziovirtuale il tempo di invio dei prodotti sia calcolato sullabase di un algoritmo complicato, che tiene conto della suapresenza in magazzino, dal grossista e le informazionisull'esaurimento delle scorte. Il metodo che fornisce iltempo di consegna opererebbe solo nei campi della classeBook. L'aggiunta del nuovo metodo getShippingDate() nellaclasse Book è la soluzione ideale per il problemadescritto. Vala la pena anche ricordare uno dei metodistandard : [NomeTabella]Base::hydrate(ResultSet $rs).Risponde il riem-pimento dell'oggetto dati, creato nel DBed è il luogo ideale per il riempimento di tutti icampi di calcolo, che possono presentarsi nell'oggetto(non possiamo farlo nel costruttore, perché questoè invocato da Propel, prima del riempimento del campooggetto).

L'applicazione di una modifica alla suddetta classeè l'esecuzione di determinate operazioni allamodifica dei dati.

Restando al nostro esempio del negozio on-line poniamo che,all'aggiunta di un nuovo prodotto, vogliamo inviareun'e-mail al traduttore, con la preghiera di tradurre ledescrizioni in altre lingue. Grazie alla classeBase[NomeTabella] disponiamo di un unico luogo centrale nelcodice, dove vengono eseguite le operazioni di trascrizionenel DB metodo doSave(). Un esempio di tale trascrizioneè presentato nel Listing 7.

Listing 7. Scrittura dei metodi doSave

 

<?phprequire_once 'bookstore/om/BaseBook.php';class Book extends BaseBook{protected function doSave($con){mail("traduttore@example.com" , "Nuovo libro" ,"Aggiunto nuovo libro nell'isbn ".$this->getISBN());parent::doSave($con);}}?>

 

 

La classe [NomeTabella]Peer, che amplia Base[NomeTabella]Peercontiene i metodi statistici generali, relativi alraccoglimento e alla trascrizione dei dati. Sembra che, inpratica, verrà modificata generalmente allo scopo diaggiungere un metodo di ricerca dei dati. Se nella nostraapplicazione sono ricorrenti le query sugli oggettisoddisfacenti criteri specifici (ad es. raccolta deglielenchi di libri disponibili solo in un dato momento), valela pena scrivere queste query in forma di metodo statisticonella classe [NomeTabella]Peer. Questi metodi normalmente sichiamano in inglese findBy[NomeCondizione], ed il lorocompito è la formulazione di una query concreta(può essere parametrica), espressa in Criteria API oSQL. Questi metodi che restituiscono elenchi di risultati,non solo ci risparmiano la scrittura delle stesse query, maanche ci permettono di cambiare le condizioni di ricercasenza toccare le parti restanti dell'applicazione.

<<< Precedente -  Continua >>>