Gestione efficace dei database con PHP 5 (Parte VI)

Pagina 6 di 8

Struttura dei dati

Nelle applicazioni complesse non operiamo solamente sulle tabelle nel DB, ma sull'insieme dei rapporti reciproci tra tabelle. Propel possiede meccanismi, che ci tolgono una parte del carico di lavoro, relativo alla manutenzione manuale delle dipendenze tra record nelle tabelle. Queste caratteristiche di Propel, le abbiamo già incontrate nel Listing 2, dove il richiamo dei metodi $book->setPublisher($pub) ha provocato la trascrizione dell'oggetto editori e dell'oggetto libri con i relativi identificatori editori in una chiave esterna.

Per utilizzare il supporto di Propel nel servire la relazione, dovremo dapprima informarlo sui collegamenti tra le singole tabelle. Così come le altre informazioni sulla struttura fisica del DB, le relazioni verranno definite nel file XML. Per fare mente locale, guardiamo il Listing 6.

Listing 6. Definizione della relazione uno-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 classe BookPeer provocala generazione di diversi metodi aggiuntivi, tra cui.: BookPeer::getPublisher() e BookPeer::setPublisher($pub). Questi metodi operano sugli oggetti interi, e non sui loro identificatori, quindi, sarà facilissimo leggere o modificarne i dati relativi.

Anche nella classe BaseBookPeer si trova un frammento di codice interessante: BaseBookPeer::doSelectJoinPublisher(Criteria $c). Questo metodo permette di richiedere quali libri soddisfanoil criterio $c e contemporaneamente, di raccogliere i dati dell'editore correlati ad un certo libro. Questo è un facile modo di costruire query rivolte agli oggetti in piùdi una singola tabella.

A parte la relazione da uno a molti, nel progetto reale incontriamo anche collegamenti del tipo da molti a molti. Il sistema di mappatura degli oggetti nella tabella adottato da Propel è un po' semplificato, affinché le classi corrispondano quasi esattamente alle tabelle nel DB. Questa regola è trasmessa anche alle tabelle collegate. Purtroppo, Propel non maschera completamente il fatto che esistono tabelle intermedie: queste vanno esplicitamente dichiarate nel file dello schema XML.

Le relazioni di diverso tipo non è l'uni-ca disposizione della struttura dati, che è supportata da Propel. Questa libreria offre anche un semplice supporto perla gerarchia dei settori e della struttura ad albero.

 

Ampliamento delle classi generate

Se guardiamo attentamente i file generati da 118-propel-generator (Fig. 4 e 5), ci rendiamo conto che le classi create nella cartella principale sono praticamente vuote, sono state ampliate solo le classi collocate nella sottocartella om. Questi scheletri sono appositamente preparati per la modifica e l'ampliamento delle funzionalità standard.

All'inizio osserviamo le classi di nome [NomeTabella], ad es. Book. Viene ampliata dalla classe BaseBook e concet-tualmente corrisponde ai dati ed alle operazioni nel record unico della tabella nel DB. Questo è il luogo ottimale, per aggiungere comportamenti specifici per l'og-getto businnes. Diciamo che, nel nostro negozio virtuale il tempo di invio dei prodotti sia calcolato sulla base di un algoritmo complicato, che tiene conto della sua presenza in magazzino, dal grossista e le informazioni sull'esaurimento delle scorte. Il metodo che fornisce il tempo di consegna opererebbe solo nei campi della classe Book. L'aggiunta del nuovo metodo getShippingDate() nella classe Book è la soluzione ideale per il problema descritto. Vala la pena anche ricordare uno dei metodi standard : [NomeTabella]Base::hydrate(ResultSet $rs). Risponde il riem-pimento dell'oggetto dati, creato nel DB ed è il luogo ideale per il riempimento di tutti i campi di calcolo, che possono presentarsi nell'oggetto (non possiamo farlo nel costruttore, perché questo è invocato da Propel, prima del riempimento del campo oggetto).

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

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

Listing 7. Scrittura dei metodi doSave

 

<?php

require_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]Peer contiene i metodi statistici generali, relativi al raccoglimento e alla trascrizione dei dati. Sembra che, in pratica, verrà modificata generalmente allo scopo di aggiungere un metodo di ricerca dei dati. Se nella nostra applicazione sono ricorrenti le query sugli oggetti soddisfacenti criteri specifici (ad es. raccolta degli elenchi di libri disponibili solo in un dato momento), vale la pena scrivere queste query in forma di metodo statistico nella classe [NomeTabella]Peer. Questi metodi normalmente si chiamano in inglese findBy[NomeCondizione], ed il loro compito è la formulazione di una query concreta (può essere parametrica), espressa in Criteria API o SQL. Questi metodi che restituiscono elenchi di risultati, non solo ci risparmiano la scrittura delle stesse query, ma anche ci permettono di cambiare le condizioni di ricerca senza toccare le parti restanti dell'applicazione.

<<< Precedente  -  Continua >>>

 



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Luca
Ti è piaciuto l'articolo?