Changes between Initial Version and Version 1 of WF/RecomendacoesdeusodeBancodeDados


Ignore:
Timestamp:
07/24/07 15:01:38 (17 years ago)
Author:
trac
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • WF/RecomendacoesdeusodeBancodeDados

    v1 v1  
     1== Classe == 
     2 A classe que é utilizada nos processos de Workflow para fazer conexão com o banco de dados é a wf_db. Esta classe faz uso do [http://adodb.sourceforge.net ADOdb] como camada de abstração de banco de dados. 
     3 
     4A documentação da classe pode ser vista neste [http://doc.workflow.celepar.parana/api/Workflow/local/wf_db.html link] 
     5 
     6Os métodos básicos da classe são: 
     7 
     8 * ''connect'' - conecta-se ao banco de dados (por padrão, conecta-se ao banco de dados onde da base de dados do processo de Workflow); 
     9 
     10 * ''disconnect'' - desconecta-se do banco de dados; 
     11 
     12 * ''query'' - executa um comando SQL no banco de dados. 
     13 
     14 
     15 
     16== Objeto == 
     17 
     18Oobjetodaclassewf_dbjávemcriadoporpadrãonodesenvolvimentoutilizandooMVCproposto-[wiki:WF_MetodologiadeDesenvolvimento] 
     19. 
     20 
     21Ele pode ser acessado em qualquer classe model através do atributo {{$this->model}} 
     22 
     23 
     24 
     25== Bind == 
     26 
     27A versão atual do ADOdb utilizada permite a utilização de bind para a execução de queries. A idéia do bind é aproveitar o mesmo plano de execução para as mesmas ações. Na utilização do bind os valores (inseridos, atualizados ou de consulta) são separados da query. Exemplo de utilização de bind: 
     28 
     29{{{ 
     30 
     31/* SEM BIND */ 
     32 
     33$this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(1, 'João')"); //plano de execução 1 
     34 
     35$this->DAO->query("INSERT INTO usuario(usuario_id, nome) VALUES(2, 'Maria')"); //plano de execução 2 
     36 
     37 
     38 
     39/* COM BIND */ 
     40 
     41$this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(1, 'João')); //plano de execução 3 
     42 
     43$this->DAO->query('INSERT INTO usuario(usuario_id, nome) VALUES(?, ?)', array(2, 'Maria')); //plano de execução 3 
     44 
     45}}} 
     46 
     47Repare que utilizando o bind, o plano de execução para as queries é o mesmo pois, a única coisa que muda são dos dados, a query é a mesma. Já sem a utilização de bind, as queries são diferentes, uma vez que os dados fazem parte da query, gerando diferentes queries para diferentes dados. Outras vantagens de se utilizar o bind sobre o método "tradicional" são: 
     48 
     49 * O parser do banco de dados não precisa analisar queries que podem ser de grande tamanho devido aos dados que estão sendo inseridos (e.g. inserção de arquivos em banco, neste caso a query terá praticamente o tamanho do arquivo inserido); 
     50 
     51 * Proteção prática e robusta contra [http://en.wikipedia.org/wiki/SQL_injection SQL Injection]. 
     52 
     53Como pode ser visto no exemplo, ao invés de se inserir os valores na query, utiliza-se {{?}} para cada valor e, depois os valores são passados em uma {{array}} como segundo parâmetro do método query. Os itens da array seguem a ordem das {{?}} utilizadas. 
     54 
     55 
     56 
     57== Utilização == 
     58 
     59Antes de utilizar o objeto para acesso ao Banco de Dados, é necessário conectá-lo ao banco. Para isto, basta chamar o método {{connect}}. Caso o banco que se quer conectar é o banco do próprio processo, não é necessário passar parâmetros, sendo a chamada realizada da seguinte maneira: 
     60 
     61{{{ 
     62 
     63$this->DAO->connect(); 
     64 
     65}}} 
     66 
     67Em todos os exemplos vamos considerar que a conexão com o Banco de Dados já foi feita. 
     68 
     69=== SELECT === 
     70 
     71{{{ 
     72 
     73/* Exemplo 01 */ 
     74 
     75$resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario'); 
     76 
     77$data = array(); 
     78 
     79while ($row = $resultSet->fetchRow()) 
     80 
     81        $data[] = $row; 
     82 
     83/* a variável $data será uma array com os valores selecionados */ 
     84 
     85echo $data[0]['nome']; //exemplo de acesso aos dados (nome do primeiro registro retornado) 
     86 
     87 
     88 
     89/* Exemplo 02 */ 
     90 
     91$resultSet = $this->DAO->query('SELECT usuario_id, nome FROM usuario WHERE (nome = ?)', array('José')); 
     92 
     93$data = array(); 
     94 
     95while ($row = $resultSet->fetchRow()) 
     96 
     97        $data[] = $row; 
     98 
     99}}} 
     100 
     101 
     102 
     103=== INSERT === 
     104 
     105{{{ 
     106 
     107$result = $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(1, 'DISER')); 
     108 
     109if ($result) 
     110 
     111        echo "OK"; 
     112 
     113else 
     114 
     115        echo "Erro na execução da query"; 
     116 
     117}}} 
     118 
     119 
     120 
     121=== UPDATE === 
     122 
     123{{{ 
     124 
     125/* troca o nome do usuário José para Joselito 
     126 
     127$result = $this->DAO->query("UPDATE usuario SET nome = ? WHERE (nome = ?)", array('Joselito', 'José')); 
     128 
     129}}} 
     130 
     131 
     132 
     133=== DELETE === 
     134 
     135{{{ 
     136 
     137/* apaga o usuário cujo ID é 3 */ 
     138 
     139$result = $this->DAO->query("DELETE FROM usuario WHERE (usuario_id = ?)", array(3)); 
     140 
     141}}} 
     142 
     143 
     144 
     145=== Casos Especiais === 
     146 
     147==== Inserção de Arquivos no Banco de Dados ==== 
     148 
     149O procedimento para inserir o conteúdo de um arquivo no Banco de Dados, requer uma pequena modificação que faz o tratamento do conteúdo antes de inseri-lo. Este tratamento é feito através da chamada ao método {{escapeBytea}}: 
     150 
     151{{{ 
     152 
     153/* supondo que $bin possua o conteúdo do arquivo */ 
     154 
     155$bin = $this->DAO->escapeBytea($bin); 
     156 
     157$result = $this->DAO->query("INSERT INTO tabela_arquivo(nome, conteudo) VALUES(?, ?)", array('arquivo.dat', $bin)); 
     158 
     159}}} 
     160 
     161 
     162 
     163==== Transações ==== 
     164 
     165Em alguns casos, é vital a utilização de transações. Sua utilização é muito simples, como pode ser visto abaixo: 
     166 
     167{{{ 
     168 
     169/* neste exemplo criamos uma área e tentamos colocar o funcionário José nesta nova área. 
     170 
     171 * Em caso de erro, esta área não deverá ser criada. 
     172 
     173 */ 
     174 
     175$result = true; 
     176 
     177$this->DAO->startTrans(); 
     178 
     179$result = $result && $this->DAO->query("INSERT INTO area(area_id, nome) VALUES(?, ?)", array(10, 'NOVA ÁREA')); 
     180 
     181$result = $result && $this->DAO->query("UPDATE funcionario SET area_id = ? WHERE (nome = ?)", array(10, 'José')); 
     182 
     183if ($result) 
     184 
     185        $this->DAO->completeTrans(); // faz o commit das alterações 
     186 
     187else 
     188 
     189        $this->DAO->failTrans(); // faz o rollback das alterações 
     190 
     191}}}