domingo, 2 de junho de 2019

Criando Bean e Dao em PHP

Olá, galerinha.

Bem, muitas vezes precisamos montar um site que acessa alguma tabela para que possamos coletar dados para apresentar na página, ou para realizar alguma tarefa específica, e não é raro termos que montar rotinas para realizar as operações CRUD nas tabelas.

A melhor forma de fazermos isso é montando classes de objetos que representem os dados da tabela e DAO para realização das operações CRUD.

Por que usar essas essas classe? As vantagens são muitas, reutilização, facilidade de manutenção, padrão, diminuição no tempo de desenvolvimento, diminuição de custo de construção.

Para começar vamos usar a tabela mostrada n modelo a seguir como base para a criação das nossas classes Bean e DAO.



Classe Bean

O que é uma classe Bean? Um Bean é uma classe que contém apenas atributos privados e os métodos de acesso para esses atributos, ou seja, é uma classe que não tem nenhum comportamento para realização de tarefas. O único objetivo é receber dados e fornecer os mesmos dados recebidos.

Quando lemos alguma linha de uma tabela precisamos guardar os valores retornados em algum lugar, esse lugar é o Bean.

Por padrão o nome da classe Bean é o mesmo da tabela, além disso toda classe deve ter seu nome iniciado com letra maiúscula, então o nome da nossa classe será Produto. Veja como fica representado na imagem de um UML.



Você pode observar o sinal '-' antes de cada atributo, isso indica que os mesmos são privados. Por outro lado você pode ver o sinal '+' antes de cada método, o que indica que todos são públicos. Então, como pode ser deduzido, a única forma de termos acesso aos valores dos atributos, seja para escrever ou ler nos mesmos, é através dos métodos. Por isso o nome método de acesso.

Por padrão de nomenclatura os métodos e atributos começam com letra minúscula e a cada mudança de palavra colocamos uma letra maiúscula. Além disso os métodos de acesso só podem ser de dois tipos, ou são de escrita ou são de leitura. Caso sejam de escrita deverão ter o prefixo set e se forem de leitura deverão ter o prefixo get e, em qualquer dos casos, após o prefixo deverá ter o nome do atributo iniciado com letra maiúscula.

Criar uma classe no PHP é fácil se você já conhece algo de orientação a objeto. Mas se não, aí é só criar um arquivo com o código a seguir. O nome do arquivo deverá ser o mesmo nome da classe, lembrando que precisa começar com letra maiúscula e ter a extensão php.


<?php class Produto {     private $codigo;     private $descricao;     private $preco;
    /********************************************      Get of atribute codigo     ********************************************/     public function getCodigo() {         return $this->codigo;     }
    /********************************************      Set of atribute codigo     ********************************************/     public function setCodigo($codigo) {         $this->codigo = $codigo;     }
    /********************************************      Get of atribute descricao     ********************************************/     public function getDescricao() {         return $this->descricao;     }
    /********************************************      Set of atribute descricao     ********************************************/     public function setDescricao($descricao) {         $this->descricao = $descricao;     }
    /********************************************      Get of atribute preco     ********************************************/     public function getPreco() {         return $this->preco;     }
    /********************************************      Set of atribute preco     ********************************************/     public function setPreco($preco) {         $this->preco = $preco;     } }
?>




Classe DAO

A classe DAO (Database Access Object) é responsável por executar todas as operações na base de dados. Ela tem ser capaz de rea lizar as operações de criação, leitura, atualização e deleção de dados na tabela. Essas operações chamamos de CRUD (Create, Read, Update, Delete).

O UML que representa essa classe está na imagem a seguir.



A classe ProdutoDao possui um único atributo. Esse atributo deverá receber uma conexão válida para que os métodos possam ser executados com sucesso.


Lembrando que o arquivo deverá ter o mesmo nome que a classe, assim nosso arquivo deverá se chamar ProdutoDao.php e irá começar com s seguintes linhas:


<?php include_once("Produto.php"); class ProdutoDao { public $conn;

Repare que faz inclusão do arquivo que contém a classe Produto, pois será utilizada.

O método create tem por obrigação incluir uma linha com os dados dos produtos, por isso o argumento que ele recebe um objeto da classe Produto. Ou seja, antes de executarmos esse método devemos instanciar um objeto Produto, colocar os valores nos seus atributos para depois executar o método create. Caso a operação tenha terminado com sucesso irá retornar um valor lógico true, caso contrário retornará false.

O código fonte do método é como segue.

    /********************************************      create method     ********************************************/     public function create($bean) {
        if
(!$this->conn) {         return false;         }
        $sql
= "Insert Into produto (                     codigo,                     descricao,                     preco          )          Values (?,?,?)";
        /*** Do prepare ***/         if(!($prdstm = @mysqli_prepare($this->conn,$sql)) ) {             return false;         }         else {             $var_codigo = $bean->getCodigo();             $var_descricao = $bean->getDescricao();             $var_preco = $bean->getPreco();
if(!($prdstm->bind_param('iss',                  $var_codigo,                  $var_descricao,                  $var_preco ) ) ) {
return false; }
if($prdstm->execute()) { $prdstm->close(); return true; }
else { return false; }
}/* Finalizing method */ }




O método read usa um do dois argumentos. Você deve informar apenas o primeiro argumento caso tenha a chave primária para realizar a consulta, neste caso o método read retornará um objeto da classe Produto com seus atributos com os valores retornados da tabela. Porém, se você não tem a chave primária mas deseja fazer a consulta utilizando uma outra condição, então o primeiro argumento deverá ser vazio e coloque sua condição, respeitando os atributos da tabela, no segundo argumento. Neste caso o método retornará um array de objetos Produto. Tome cuidado ao usar condições que não sejam a chave primária pois poderá acarretar lentidão na pesquisa de banco de dados e por consequência na apresentação da página, se a tabela for grande coloque índices nas colunas que podem ser usadas como condição de pesquisa. Caso ocorra algum erro o método devolverá o valor lógico false.


O código do método read está a seguir.

    /********************************************      read method     ********************************************/ public function read($var_codigo, $wherePar="") { if(!$this->conn) { return false; } if($wherePar == "") { $sql = "Select * From produto Where codigo = ?"; } else { $sql = "Select * From produto Where $wherePar"; }

/*** Do prepare ***/
if(!($prdstm = @mysqli_prepare($this->conn,$sql)) ) { return false; } else { if($wherePar == "") { /*************************************** * Read just one line from table. * Just the id parameter will be used */ if(!($prdstm->bind_param('i',$var_codigo )) ) { return false; } if($prdstm->execute()) { $prdstm->bind_result(                      $var_codigo,                      $var_descricao,                      $var_preco ); if ( $prdstm->fetch() ) { $bean = new Produto();                      $bean->setCodigo($var_codigo);                      $bean->setDescricao($var_descricao);                      $bean->setPreco($var_preco); $prdstm->close(); return $bean; } else { $prdstm->close(); return null; } } else { $prdstm->close(); return false; } } else { /*************************************** * Read one or more lines from table. * The id parameter will not be used, * the where parameter will be used instead. */ $beanArray = array(); if($prdstm->execute()) { $prdstm->bind_result(
                     $var_codigo,                      $var_descricao,                      $var_preco ); while ( $prdstm->fetch() ) {
$bean = new Produto();                      $bean->setCodigo($var_codigo);                      $bean->setDescricao($var_descricao);                      $bean->setPreco($var_preco);
$beanArray[] = $bean; } $prdstm->close(); return $beanArray; } else { $prdstm->close(); return false; } } } /* Finalizing method */ }



O método update recebe um objeto da classe Produto como argumento. É importante que a chave primária esteja correta e todos os atributos preenchidos pois todos os valores serão atualizados na tabela. Repare que caso o banco de dados não encontre nenhuma linha com a chave primária não será considerado erro. Por isso caso seja necessário, faça uma pesquise antes para saber se a chave primária existe na tabela antes de realizar a operação de update. Se ocorrer alguma falha no update será retornado o valor lógico false.

A seguir está o código do método update.

    /********************************************      update method     ********************************************/ public function update($bean) { if(!$this->conn) { return false; } $sql = "Update produto Set " . " codigo = ?, " . " descricao = ?, " . " preco = ? " . "Where codigo = ?"; /*** Do prepare ***/         if(!($prdstm = @mysqli_prepare($this->conn,$sql)) ) { return false; } else {             $var_codigo = $bean->getCodigo();             $var_descricao = $bean->getDescricao();             $var_preco = $bean->getPreco(); if(!($prdstm->bind_param('issi',                                      $var_codigo,                                      $var_descricao,                                      $var_preco,                      $var_codigo )) ) { return false; } if($prdstm->execute()) { $prdstm->close(); return true; } else { $prdstm->close(); return false; } } /* Finalizing method */ }




O método delete só precisa da chave primária como argumento para realizar sua operação. Caso ocorra alguma falha será retornado o valor lógico false. Repare que caso o banco de dados não encontre nenhuma linha com a chave primária não será considerado erro. Por isso caso seja necessário, faça uma pesquise antes para saber se a chave primária existe na tabela antes de realizar a operação de delete.

 A seguir está o código fonte do método delete.


    /********************************************      delete method     ********************************************/ public function delete($var_codigo) { if(!$this->conn) { return false; } $sql = "Delete From produto Where codigo = ?"; /*** Do prepare ***/ if(!($prdstm = @mysqli_prepare($this->conn,$sql)) ) { return false; } else { if(!($prdstm->bind_param('i',$var_codigo )) ) { return false; } if($prdstm->execute()) { $prdstm->close(); return true; } else { $prdstm->close(); return false; } } /* Finalizing method */ }


E o arquivo termina com essas poucas linhas.

} ?>




Exemplo de utilização do DAO.

Vamos fazer um programa para inserir uma linha na tabela.

<?php
// Inclusão das classes que serão utilizadas include once("Produto.php"); include once("ProdutoDao.php");
// Dados para conexão com o banco de dados $db = 'teste'; $usr = 'usr'; $pwd = '123'; $srv = 'localhost';
// Realização da conexão if($conexao = @mysqli_connect($srv,$usr,$pwd,$db)) { // Conexão com BD foi realizada // Instancia classe Bean e seta seus atributos $p = new Produto(); $p->setCodigo(7); $p->setDescricao("Produto Teste"); $p->setPreco(8.50);
// Instancia objeto da classe DAO e coloca objeto de conexão // no seu atributo conn $pd = new ProdutoDao(); $pd->conn = $conexao; // Executa método update $r = $pd->create($p); if($r == false) echo "Erro ao tentar inserir na tabela. \n"; else echo "Linha inserida com sucesso.\n"; } else { //Conexão com o banco de dados falhou echo "Erro ao tentar conectar ao banco de dados\n"; } ?>



É isso, gente. Agora é botar a mão na massa e praticar. Faça programas para usar os outros métodos.


Um forte abraço e até a próxima.