Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Qual a melhor forma de reduzir o número de consultas quando a Classe DAO possui métodos que utilizam o mesmo resultado?


Essa resposta depende da estrutura de consulta atual, onde não há condicionais
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();
    }
}

O processo de pensamento por trás disso é que, como os resultados serão sempre os mesmos (ignore, atualize, insira, exclua por enquanto), não há necessidade de manter uma cópia dos resultados em cada objeto.

Como você apontou, as atualizações de tabela deixarão o conjunto de resultados armazenado fora de sincronia com o objeto; é aqui que eu gostaria de voltar um pouco e dizer que se o conjunto de resultados para um determinado objeto só precisa estar atualizado no momento da criação, use membros normais de objeto.

Também vale a pena considerar de forma independente e em conjunto com o comentário anterior se a consulta mudará ou não e, se isso acontecer, exigirá que os membros do objeto sejam gerados. Se a consulta não mudar, não há com o que se preocupar - exceto o ponto anterior. Se isso mudar, suas opções são mais ou menos cobertas nos exemplos a seguir.
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));
    }
}

Neste exemplo, você ainda está usando um método estático para gerar a consulta, mas está passando membros não estáticos para o processo/ Neste ponto (consulte o comentário sobre objetos atualizados no momento da criação), você pode armazenar o resultados dentro do membro estático ou passe-os de volta para a função __construct() e armazene na instância do objeto.

Depois, há o potencial de que a consulta que você está usando seja um pouco mais complicada do que simplesmente solicitar determinados campos, de modo que criar um array multidimensional para passar para a função estática seria mais incômodo do que vale a pena. Nesse caso, você pode dividir o buildAndRunQuery() em buildQuery() - método de instância e 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);
    }
}

Nesse caso, há algumas opções para lidar com a consulta gerada antes de chamar Foo::runQuery().

Claro que sempre existe a possibilidade de você não querer criar e executar a consulta de forma síncrona ou mesmo no construtor.

Em conclusão, eu pessoalmente sinto que para métodos que interagem com serviços independentes do próprio objeto, como Sql ou talvez DOMDocument focado, ou interações de objetos semelhantes, é melhor usar métodos estáticos onde eles são relevantes e não cortar seu nariz para apesar de seu rosto (desnecessariamente complexo etc). Claro que tudo isso precisa ser considerado em uma base por classe.