Olá Pessoal
Depois de um longo tempo de inatividade, estou de volta. Devido a total falta de tempo, não voltarei a postar com a mesma frequência com que vinha postando antes. Irei também, finalizar esta série. A partir de agora, sempre que eu fizer alguma atualização e que esta seja significativa, informo o que foi feito.
Coloquei os fontes no Google Code. Para baixá-los, acesse: code.google.com/p/blog-luiz-orm/
Alguns leitores do blog se mostraram interessados em contribuir com o projeto. Achei interessante a ideia. Portanto, quem desejar, sinta-se à vontade. Toda ajuda será bem vinda!
Nos últimos dias, voltei a atualizar os fontes, pois estou utilizando-o em um sistema de controle de estoque. Abaixo, falo um pouco sobre as alterações mais importantes.
Alguns Ajustes
Renomeei as units para prsBase, prsAtributos, prsDaoIBX.
Separando Responsabilidades
Nossas classes DAO estavam sobrecarregadas, com muitas responsabilidades. Fugimos um pouco das boas práticas (sem querer querendo viu?!). Por exemplo: TDaoIBX, além do próprio DAO ainda tinha que lhe dar com a Conexão e com a Transação. Agora, retirei dela esta alçada e criei novas classes na unit prsDaoIBX:
[sourcecode language=”Delphi”]
TTransacaoIbx = class(TTransacaoBase)
private
// transação para crud
FTransaction: TIbTransaction;
public
constructor Create(ABanco: TIBDatabase);
destructor Destroy; override;
function InTransaction: Boolean; override;
procedure Snapshot;
procedure Read_Commited;
procedure StartTransaction; override;
procedure Commit; override;
procedure RollBack; override;
property Transaction: TIbTransaction read FTransaction write FTransaction;
end;
TConexaoIbx = class(TConexaoBase)
private
// conexao com o banco de dados
FDatabase: TIBDatabase;
// transação para consultas
FTransQuery: TIbTransaction;
public
constructor Create();
destructor Destroy; override;
function Conectado: Boolean; override;
procedure Conecta; override;
property Database: TIBDatabase read FDatabase write FDatabase;
property TransQuery: TIbTransaction read FTransQuery write FTransQuery;
end;
[/sourcecode]
Vamos à classe TDaoIBX
Nossa classe Dao para IBX sofreu alguns ajustes importantes:
[sourcecode language=”Delphi”]
TDaoIbx = class(TDaoBase)
private
FConexao: TConexaoIbx;
// query para execução dos comandos crud
Qry: TIBQuery;
Function DbToTabela<T: TTabela>(ATabela: TTabela; ADataSet: TDataSet):
TObjectList<T>;
protected
// métodos responsáveis por setar os parâmetros
procedure QryParamInteger(ARecParams: TRecParams); override;
procedure QryParamString(ARecParams: TRecParams); override;
procedure QryParamDate(ARecParams: TRecParams); override;
procedure QryParamCurrency(ARecParams: TRecParams); override;
procedure QryParamVariant(ARecParams: TRecParams); override;
// métodos para setar os variados tipos de campos
procedure SetaCamposInteger(ARecParams: TRecParams); override;
procedure SetaCamposString(ARecParams: TRecParams); override;
procedure SetaCamposDate(ARecParams: TRecParams); override;
procedure SetaCamposCurrency(ARecParams: TRecParams); override;
function ExecutaQuery: Integer; override;
public
constructor Create(AConexao: TConexaoIbx; ATransacao: TTransacaoIbx);
destructor Destroy; override;
// dataset para as consultas
function ConsultaSql(ASql: string): TDataSet; override;
function ConsultaTab(ATabela: TTabela; ACampos: array of string): TDataSet; override;
function ConsultaGen<T: TTabela>(ATabela: TTabela; ACampos: array of string): TObjectList<T>;
// pega campo autoincremento
function GetID(ATabela: TTabela; ACampo: string): Integer; override;
// recordcount
function GetRecordCount(ATabela: TTabela; ACampos: array of string): Integer; override;
// crud
function Inserir(ATabela: TTabela): Integer; override;
function Salvar(ATabela: TTabela): Integer; override;
function Excluir(ATabela: TTabela): Integer; override;
function Buscar(ATabela: TTabela): Integer; override;
end;
[/sourcecode]
Destaque para:
- Linha 3 – FConexao do tipo TConexaoIbx – onde definimos qual conexão iremos utilizar
- Linha 34 – Função de consulta que devolve uma lista de objetos genérica
- Linha 38 – Renomeei o método de auto incremento para GetID e agora passamos um objeto e não mais uma string
- Linha 42 – Método para pegar a contagem de registros em determinada tabela
Novos Atributos
A unit prsAtributos também sofreu alguns ajustes e novas implementações:
[sourcecode language=”Delphi”]
/// <summary>
/// Atributos de Chave Primaria e Relacionamentos
/// </summary>
AttPK = class(TCustomAttribute)
end;
/// <summary>
/// Atributos de Validação
/// </summary>
AttBaseValidacao = class(TCustomAttribute)
private
FMensagemErro: string;
procedure SetMessagemErro(const Value: string);
public
property MessagemErro: string read FMensagemErro write SetMessagemErro;
end;
AttNotNull = class(AttBaseValidacao)
public
constructor Create(const ANomeCampo: string);
function ValidarString(Value: string): Boolean;
function ValidarInteger(Value: Integer): Boolean;
function ValidarFloat(Value: Double): Boolean;
function ValidarData(Value: Double): Boolean;
end;
AttMinValue = class(AttBaseValidacao)
private
FValorMinimo: Double;
public
constructor Create(ValorMinimo: Double; const ANomeCampo: string);
function Validar(Value: Double): Boolean;
end;
AttMaxValue = class(AttBaseValidacao)
private
FValorMaximo: Double;
public
constructor Create(ValorMaximo: Double; const ANomeCampo: string);
function Validar(Value: Double): Boolean;
end;
[/sourcecode]
Como pode ser visto, quando comparamos com o último fonte disponibilizado aqui no blog, houve uma mudança radical e será necessário rever as classes relativas às tabelas do banco de dados. Abaixo, um exemplo de como devemos criar nossas classes:
[sourcecode language=”Delphi”]
uses PrsBase, PrsAtributos, Cidade;
type
[AttTabela(‘Cliente’)]
TCliente = class(TTabela)
private
FID: Integer;
FNOME: string;
FCIDADEID: Integer;
procedure SetID(const Value: Integer);
procedure SetNOME(const Value: string);
procedure SetCIDADEID(const Value: Integer);
public
[AttPk]
[AttNotNull(‘Código do cliente’)]
property ID : Integer read FID write SetID;
[AttNotNull(‘Nome do Cliente’)]
property NOME : string read FNOME write SetNOME;
[AttNotNull(‘Código da Cidade’)]
property CIDADEID: Integer read FCIDADEID write SetCIDADEID;
end;
[/sourcecode]
O trecho acima refere-se a unit Clientes que está nos fontes.
Eu ainda não estou satisfeito com relação ao atributo que verifica se o campo está vazio (AttNotNull). Isso significa que em breve poderemos ter novas alterações nesta unit.
Como podem observar, atualizei apenas o Dao do IBX. Isso porque atualmente estou com problemas com o UIB, depois que passei para meu novo computador. Por isso, os fontes também estão sem esta unit.
Pensei em fazer um vídeo demonstrando e testando tudo o que foi feito até aqui, mas encontrei dificuldade para achar um programa que me permitisse gravar, assim como Camtasia faz, mas que fosse free (Claro!). Se tiverem um pra me indicar, postem nos comentários.
É isso! Espero que gostem deste post. Abraços e até mais!
Atualizei o post às 17 hs com os atributos e classe cliente corretos. Eu havia enviado uns fontes desatualizados. Mas agora, está tudo ok.
Grande, Luiz os seus post são excelentes.
Como já havia dito em outro post, eu fiz o DAO para uso com o FireDac e implementei os campos BLOB,
percebi que mesmo nesta ultima atualização vc não implementou os campos BLOB, poderia me dizer se é por estratégia ou vc não faz uso deles, e por ultimo se vc quiser eu envio o DAO com FireDac embora necessite ainda de melhorias já que o FireDac se conecta com os principais SGDB’s e eu fixei a conexão com o FIREBIRD.
Muito Bom, estava aguardando o retorno!
Luiz meus parabéns, excelente post estou aprendendo muito com você. Muito obrigado pela aula.
Mauro Garcia, tudo bem ? Será que você poderia me enviar esse DAO com Firedac ? Muito obrigado.
Boa tarde Alexandre, desculpe a demora mas com as mudanças para nf-e 3.10 o tempo ficou curto, mas me adiciona no skype garciamauro@msn.com e eu te passo sim.
Já te enviei uma solicitação Obrigado.
Você já tentou usar nesse post uma tabela com campo auto-incremento ? se sim poderia me dizer como fez ou como fazer ? Obrigado.
Luiz, quero primeiramente lhe parabenizar pelo artigo, super didático, objetivo e bastante útil… estou implementando (creio que o colega Jonathan também já fez) com o FireDac e gostaria de contribuir com o projeto, vi que o código se encontra no GoogleCode porém, seria interessante organizar o que se deve ser implementado (requisitos e/ou melhorias), aguardo retorno… abraços
Olá Gustavo
Estou pensando passar a usar o git/github. Lá podemos criar as histórias, os participantes, brunchs, etc…
Só me dá um tempinho… e já aproveito para pedir desculpas… aqui, a água já está acima do nariz (aka tempo esgotado!). 😉
Boa tarde, você cita que renomeou o método de auto incremente para GetID. Só que não encontrei nada sobre como era o método antes e sobre o GetID eu só encontrei a assinatura. Poderia disponibilizar este método completo?
Olá Tiago
No git você encontra a última versão:
https://github.com/luizsistemas/ORM-Basico-Delphi
Estou envolvido em novos projetos aqui, em virtude disso o projeto está um tanto abandonado.
Abraços.
Parabéns.. ótimo artigo/curso..