sql >> Base de Datos >  >> RDS >> Mysql

¿Cuál es la mejor manera de reducir la cantidad de consultas cuando la Clase DAO tiene métodos que usan el mismo resultado?

Esta respuesta depende de la estructura de consulta actual, donde no hay condicionales

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

El proceso de pensamiento detrás de esto es que, dado que los resultados siempre serán los mismos (ignorar, actualizar, insertar, eliminar por ahora), no es necesario guardar una copia de los resultados en cada objeto.

Como señaló, las actualizaciones de la tabla desincronizarán el conjunto de resultados almacenados con el objeto; aquí es donde me gustaría retroceder un poco y decir que si el conjunto de resultados para un objeto dado solo tiene que estar actualizado en el momento de la creación, entonces use miembros de objetos normales.

También vale la pena considerar tanto de forma independiente como junto con el comentario anterior si la consulta cambiará o no y, si lo hace, requerirá que se generen miembros de objetos. Si la consulta no cambia, no hay nada de qué preocuparse, excepto el punto anterior. Si cambia, sus opciones están más o menos cubiertas en los siguientes ejemplos.

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

En este ejemplo, todavía está utilizando un método estático para generar la consulta, pero está pasando miembros no estáticos para el proceso. En este punto (consulte el comentario sobre los objetos actualizados en el momento de la creación), puede almacenar el resultados dentro del miembro estático o devolverlos a la función __construct() y almacenarlos en la instancia del objeto.

Luego existe la posibilidad de que la consulta que está utilizando sea un poco más complicada que simplemente solicitar ciertos campos, de modo que crear una matriz multidimensional para pasar a la función estática sería más complicado de lo que vale. En cuyo caso, puede dividir buildAndRunQuery() en buildQuery() - método de instancia y método estático runQuery() como.

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

En este caso, hay un par de opciones para manejar la consulta generada antes de llamar a Foo::runQuery().

Por supuesto, siempre existe la posibilidad de que no desee crear y ejecutar la consulta de forma síncrona o, de hecho, en el constructor.

En conclusión, personalmente creo que para los métodos que interactúan con servicios independientes del objeto en sí, como Sql o tal vez DOMDocument enfocado, o interacciones de objetos similares, es mejor usar métodos estáticos donde sean relevantes y no corten su nariz para a pesar de tu cara (innecesariamente complejo, etc.). Por supuesto, todo esto debe considerarse por clase.