Mysql
 sql >> Base de données >  >> RDS >> Mysql

Quelle est la meilleure façon de réduire le nombre de requêtes lorsque la classe DAO a des méthodes qui utilisent le même résultat ?

Cette réponse dépend de la structure de requête actuelle, où il n'y a pas de conditions

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();
    }
}

Le processus de réflexion derrière cela est que puisque les résultats seront toujours les mêmes (ignorer, mettre à jour, insérer, supprimer pour l'instant), il n'est pas nécessaire de conserver une copie des résultats dans chaque objet.

Comme vous l'avez souligné, les mises à jour de table désynchroniseront le jeu de résultats stocké avec l'objet ; c'est là que j'aimerais revenir un peu en arrière et dire que si le jeu de résultats pour un objet donné doit seulement être à jour au moment de la création, utilisez les membres d'objet normaux.

Il convient également de considérer à la fois indépendamment et en conjonction avec le commentaire précédent si la requête changera ou non et si elle le fera, elle nécessitera la génération de membres d'objet. Si la requête ne change pas, il n'y a rien à craindre - sauf le point précédent. Si cela change, vos options sont plus ou moins couvertes dans les exemples suivants.

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));
    }
}

Dans cet exemple, vous utilisez toujours une méthode statique pour générer la requête, mais vous transmettez des membres non statiques pour le processus. À ce stade (voir le commentaire sur les objets mis à jour au moment de la création), vous pouvez soit stocker le résultats dans le membre statique ou retransmettez-les à la fonction __construct() et stockez-les dans l'instance d'objet.

Ensuite, il est possible que la requête que vous utilisez soit un peu plus complexe que la simple demande de certains champs, de sorte que la création d'un tableau multidimensionnel à transmettre à la fonction statique serait plus compliquée qu'elle n'en vaut la peine. Dans ce cas, vous pouvez diviser le buildAndRunQuery() en buildQuery() - méthode d'instance et méthode statique runQuery() telle que.

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);
    }
}

Dans ce cas, il existe plusieurs options pour gérer la requête générée avant d'appeler Foo::runQuery().

Bien sûr, il est toujours possible que vous ne souhaitiez pas créer et exécuter la requête de manière synchrone ou même dans le constructeur.

En conclusion, je pense personnellement que pour les méthodes qui interagissent avec des services indépendants de l'objet lui-même, tels que Sql ou peut-être un DOMDocument ciblé, ou des interactions d'objets similaires, il est préférable d'utiliser des méthodes statiques où elles sont à la fois pertinentes et ne vous coupent finalement pas le nez pour malgré votre visage (inutilement complexe, etc.). Bien sûr, tout cela doit être considéré par classe.