Mysql
 sql >> Database >  >> RDS >> Mysql

Qual è il modo migliore per ridurre il numero di query quando la classe DAO dispone di metodi che utilizzano lo stesso risultato?

Questa risposta dipende dalla struttura della query corrente, dove non ci sono condizionali

class CategoriaDAO extends PDOConnectionFactory
{
    /*DB Connection, static member since you only need one connection*/
    private static $dbConnection;

    /*Sql result set, static since there is not conditonal and only a single table used*/
    private static $resultSet;

    private static function getConnection()
    {
            /*Connect to mysql db, set CategoriaDAO::dbConnection; */
    }

    private static function populateResultSet()
    {
            /*Run query and populate resultSet - either as sql result or parse to array - your call*/
    }
    /**
     *
     * @var PDO $conn 
     */
    private $conn;

    public function __construct()
    {
                /*Get sql connection if one hasn't already been established*/
                if(!CategoriaDAO::dbConnection)
                        $this->conn = PDOConnectionFactory::getConnection();
    }
}

Il processo di pensiero alla base di ciò è che poiché i risultati saranno sempre gli stessi (ignora, aggiorna, inserisci, elimina per ora) non è necessario conservare una copia dei risultati in ciascun oggetto.

Come hai sottolineato, gli aggiornamenti della tabella renderanno il set di risultati memorizzato non sincronizzato con l'oggetto; qui è dove vorrei tornare indietro un po' e dire che se il set di risultati per un determinato oggetto deve essere aggiornato solo al momento della creazione, usa i normali membri dell'oggetto.

Vale anche la pena considerare sia indipendentemente che in combinazione con il commento precedente se la query cambierà o meno e, in tal caso, richiederà la generazione di membri oggetto. Se la query non cambia, non c'è nulla di cui preoccuparsi, tranne il punto precedente. Se cambia, le tue opzioni sono più o meno trattate nei seguenti esempi.

class Foo{
    private $someMember;

    /*
        $params = Associative array of fields and values
    */
    private static buildAndRunQuery($params)
    {
        /*Build sql query based on the given params Array()*/
    }
    public __construct($someMemebrValue)
    {
        $this->someMember = $someMemberValue;
        Foo::buildAndRunQuery(Array("fieldName" => $this->someMember));
    }
}

In questo esempio stai ancora utilizzando un metodo statico per generare la query ma stai passando membri non statici per il processo/ A questo punto (vedi commento sugli oggetti aggiornati al momento della creazione) puoi archiviare il risultati all'interno del membro statico o passarli di nuovo alla funzione __construct() e archiviarli nell'istanza dell'oggetto.

Quindi c'è la possibilità che la query che stai utilizzando sia un po 'più complicata della semplice richiesta di determinati campi in modo tale che la creazione di un array multidimensionale da passare alla funzione statica sarebbe più fastidioso di quanto valga la pena. In tal caso potresti dividere buildAndRunQuery() in buildQuery() - metodo di istanza e metodo statico runQuery() come.

class Foo{

    private $someMember;

    /*
        $params = Associative array of fields and values
    */
    private static runQuery($query)
    {
        /*Build sql query based on the given params Array()*/
    }

    private function buildQuery()
    {
        /*Construct your query here and either return calling method or store in instance member*/
         /*Either*/
            return <Constructed query>;
        /*Or*/
           $this->query = <Constructed query>;
    }

    public __construct($someMemebrValue)
    {
        $this->someMember = $someMemberValue;
        /*As per buildQuery() comment either:*/
            Foo::runQuery($this->buildQuery());
        /*Or*/
            Foo::runQuery($this->query);
    }
}

In questo caso ci sono un paio di opzioni per gestire la query generata prima di chiamare Foo::runQuery().

Ovviamente c'è sempre la possibilità che tu non voglia creare ed eseguire la query in modo sincrono o addirittura nel costruttore.

In conclusione, personalmente ritengo che per i metodi che interagiscono con servizi indipendenti dall'oggetto stesso come Sql o forse DOMDocument focalizzato, o simili, interazioni con gli oggetti è meglio usare metodi statici dove sono entrambi rilevanti e non tagliano il naso per nonostante la tua faccia (inutilmente complessa ecc.). Ovviamente tutto questo deve essere considerato per Classe.