Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

Johnny Saymon

Obtenção de objetos grandes já persistidos

Recommended Posts

Olá!

 

Cenário: Tenho uma classe NotaFiscal que tem um relacionamento com vários outros objetos, como Cliente, Fornecedor, Produtos e etc, sendo que estes objetos ligados diretamente ainda tem seus relacionamentos com outros objetos.

 

Objetivo: Apresentar uma lista de notas fiscais quem contém poucos dados, como número da nota, nome do cliente e valor total.

 

Dúvida: Recuperar o objeto NotaFiscal e todas as suas relações em um banco de dados, por exemplo, não seria um grande problema de desempenho, visto que preciso de poucos dados? Me parece um erro obter apenas as notas sem suas relações e um exagero obter tudo. 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Seja bem vindo ao fórum,

digamos que você tenha uma classe NotaFiscal / Comprador.


O que vamos fazer? Após o comprador efetuar uma compra, vamos gerar uma nota fiscal de acordo com a compra do cliente.

<?php
class NotaFiscal {
 private $numeroNota;
 private $idPedido;
 private $nomeCliente;
 private $valorTotal;
 private $idCliente;
  
  public function __construct($idPedido, $idCliente) {
    $this->setIdProduto($idProduto);
    $this->setIdCliente($idCliente);
    $this->atribuirValores();
  }
  
  public function retornar($idPedido, $column) {
    // query select... 
    // return $valor[$column];
  }
  
  public function atribuirValores() {
    $this->setNumeroNota($this->retornar($this->getIdPedido(), "numeroNota"));
    $this->setValorTotal($this->retornar($this->getIdPedido(), "valorTotal"));
    $this->setNomeCliente($this->retornar($this->getIdCliente(), "nomeCompleto"));
                          
  }
  
  public function escreverNota() {
   $nota = "Nome: ".$this->getNomeCliente();
   $nota .= "</br>";
   $nota .= "Numero da nota: ".$this->getNumeroNota();
   $nota .= "</br>";
   $nota .= "Valor total: ".$this->getValorTotal();
   
   echo $nota;
  }
  
  //finja que tenha os getters e setters aqui
  
}

/* COMPRA FINALIZADA COM SUCESSO! ID DO PEDIDO É 2354 */
/* ID DO USUÁRIO É 23 */

$nota = new NotaFiscal(2354, 23);
$nota->escreverNota();

 

Sendo assim, só você receber o ID do pedido e passar o ID do usuário ou receber o ID do usuário diretamente na tabela pedido.

Não entendi muito bem o que você desejava fazer. 

Use o código como base para seu algoritmo.

 

Observação: Não copie o código pois vai apresentar erros.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Olá @jamesbond

 

Obrigado por responder minha pergunta, vou usar o código como exemplo para mostrar o que pretendo fazer:

 

<?php

$lista_de_notas = [
  # nf_id, cliente_id 
  [123, 1],
  [124, 2]
  [125, 3]
  [126, 1]
  [127, 2]
  # ...
];

foreach ($lista as $dados) {
  $NotaFiscal = new NotaFiscal($dados[0], $dados[1]);
  $NotaFiscal->escreverNota();
}

Com essa classe vou conseguir sem dúvidas atingir meu objetivo, mas o meu questionamento é quanto a performance disso, pois se o seu método "retornar" realmente fizer uma consulta ao banco a cada vez que for chamado, serão três consultas para cada Nota. Outro problema que não dá para mostrar com essa classe é que na minha ainda existe as classes de Fornecedor, Clientes e Produtos, todas relacionadas diretamente com nota. Assim:

 

<?php


class NotaFiscal
{
  private $Cliente;
  private $Fornecedor;
  private $produtos;
  # ...
  
  public function __construct(Cliente $Cliente, Fornecedor $Fornecedor) 
  {
    $this->Cliente = $Cliente;
    $this->Fornecedor = $Fornecedor;
    $this->produtos = [];
  }
  
  public function adicionarProduto(Produto $Produto): self
  {
    $this->produtos[] = $Produto;
    return $this;
  }
  
  # ...
}

Existe várias outras propriedades e métodos, a minha principal dúvida é quanto a obtenção das classes Cliente, Fornecedores e Produtos que também tem vários dados, quando em determinado momento só vou imprimir o número da nota e seu valor.

 

Estou fazendo isso certo?

Compartilhar este post


Link para o post
Compartilhar em outros sites
5 horas atrás, Johnny Saymon disse:

Olá @jamesbond

 

Obrigado por responder minha pergunta, vou usar o código como exemplo para mostrar o que pretendo fazer:

 

Com essa classe vou conseguir sem dúvidas atingir meu objetivo, mas o meu questionamento é quanto a performance disso, pois se o seu método "retornar" realmente fizer uma consulta ao banco a cada vez que for chamado, serão três consultas para cada Nota. Outro problema que não dá para mostrar com essa classe é que na minha ainda existe as classes de Fornecedor, Clientes e Produtos, todas relacionadas diretamente com nota. Assim:

 

Existe várias outras propriedades e métodos, a minha principal dúvida é quanto a obtenção das classes Cliente, Fornecedores e Produtos que também tem vários dados, quando em determinado momento só vou imprimir o número da nota e seu valor.

 

Estou fazendo isso certo?

 

Pesquise sobre Facade/Builder. Acho que ajuda em seu caso.

Quanto a consulta ao banco de dados, isso é relativo. Basta saber relacionar as tabelas.

Por exemplo aqui no fórum, cada mensagem corresponde a um usuário, na tabela tópicos existe a column ID USER ou seja com o ID do usuário na tabela tópico o mesmo faz uma consulta para receber o Nome do usuário.
Se um tópico tem 100 mensagens, olha quantas consultas foram executadas. Basta saber dividir as mesmas.

No seu caso, creio que não irá atrapalhar a performance.

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por Luiz Henrique
      Olá pessoas,
       
      Queria saber se há ganho de desempenho se após não precisar da variável mais eu destruir ela.

      Eu uso uma variável default aqui ex:
       
      $callback = Classe::primeiroSelect();  
      Pego os dados necessários em foreach por exemplo e reutilizo a variável $callback  em outra consulta
      $callback = Classe::segundoSelect();  
      E assim sucessivamente.
      Então vale a pena dar um unset($callback) após cada select? Ou no final do method? Ou não precisa pois não faz diferença?
       
      Obrigado.
    • Por Luiz Henrique
      Olá pessoas.
      Segue code depois explico.
       
      class Usuario { public $email; private $senha; public function alteraSenha($senha) { $this->senha = md5($senha); } } class Cliente extends Usuario { public function __construct($email = null, $senha = null) { $this->email = $email; $this->senha = ($senha); } } $cliente = new Cliente("mail@mail.com","123456"); o retorno disso é: mail@mail.com / 123456. OK
      Porém preciso tratar a senha e passar pela função alteraSenha e já tentei:
      $cliente = new Cliente("mail@mail.com"); $cliente->alterSenha('12346'); Também assim dentro da classe Cliente:
      public function setSenha($senha) { parent::alteraSenha($senha); } Dentro do __construct:
      $this->senha = alteraSenha($senha);  
      E em todas as opções, o retorno da senha fica vazio, não dá erro mas volta vazio.
      A única forma de  funcionar é fazendo a declaração diferente:
      $cliente = new Cliente(); $cliente->email = "mail@mail"; $cliente->setSenha('12356'); Dessa forma funciona, mas eu queria a declaração da outra forma para otimizar linhas.
      O que estou fazendo errado.
       
      Obrigado
    • Por Sapinn
      Boa pessoal. Então, estou fazendo um sistema para uma loja de manutenção de aparelhos eletrônicos, e eu tenho um formulário de cadastro onde eu posso inserir os dados de um cliente e os dados do seu aparelho. E eu consigo cadastrar simultaneamente cada um em suas respectivas tabelas. O que eu gostaria de fazer era assim que cadastra-se o cliente pega-se o seu id( Nesse caso o ultimo id inserido) e inserisse na tabela serviços junto. No PDO tem um jeito de fazer isso que é usando o lastInsertId() mas eu não estou sabendo como retornar esse ultimo id para fazer essa inserção
    • Por janir.matheus
      Bom dia,
       
      Preciso de ajuda ajuda para resolver o problema de SIGSEGV, basicamente tennho um zconection dentro de uma classe e recebo erro quando tento acessá-lo. Segue um trecho da classe:
      unit unt_classconexao; {$mode objfpc}{$H+} interface uses Classes, SysUtils, ZConnection, ZDataset; type { tConexao } tConexao = class private public vConector : TZConnection; function Listar_Usuarios:TZReadOnlyQuery; procedure Conectar_Banco; end; implementation { tConexao } function tConexao.Listar_Usuarios: TZReadOnlyQuery; var zrquery : TZReadOnlyQuery; begin Conectar_Banco; try zrquery := TZReadOnlyQuery.Create(nil); zrquery.Connection := vConector; zrquery.SQL.Clear; zrquery.SQL.Text := 'SELECT * from tbl_profissionais'; zrquery.Open; Listar_Usuarios := zrquery; finally end; end; procedure tConexao.Conectar_Banco; begin //vConector := TZConnection.Create(nil); vConector.HostName := 'localhost'; vConector.Port := 3306; vConector.Database := 'Caps'; vConector.Protocol := 'mysql-5'; vConector.User := 'root'; vConector.Password := ''; vConector.Connected := true; end; end. Após isso tento fazer uso dessa classe para popular um DBGrid:
      unit unt_frmprincipal; {$mode objfpc}{$H+} interface uses Classes, SysUtils, DB, Forms, Controls, Graphics, Dialogs, Menus, DBGrids, ZConnection, unt_classconexao; type { Tfrm_principal } Tfrm_principal = class(TForm) DataSource1: TDataSource; DBGrid1: TDBGrid; MainMenu_frmPrincipal: TMainMenu; MenuItem_AplicativoSair: TMenuItem; N1: TMenuItem; MenuItem_AplicativoLogin: TMenuItem; MenuItem_Aplicativo: TMenuItem; procedure MenuItem_AplicativoLoginClick(Sender: TObject); private public vConexao : tConexao; end; var frm_principal: Tfrm_principal; implementation {$R *.lfm} { Tfrm_principal } procedure Tfrm_principal.MenuItem_AplicativoLoginClick(Sender: TObject); begin //vConexao := tConexao.Create; DataSource1.DataSet := vConexao.Listar_Usuarios; end; end. A mensagem de erro que recebo dá a entender que o problema ocorre logo que o zconnection começa a ser configurado, como vocês podem ver pelos trechos comentados eu tentei instanciar o componente também sem sucesso. Não tenho experiencia com POO e tenho certeza que estou cometendo um erro bobo, então peço uma explicação sobre como resolver isso. Agradeço de antemão a quem puder me ajudar.
       
      PS. Estou usando o Lazarus.
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.