Vamos iniciar uma nova série para tratar de um tema muito importante para todo desenvolvedor de software que trabalha com Banco de Dados, ou seja, Persistência de Dados. O objetivo será criar um ORM Básico:
Mapeamento objecto-relacional (português europeu) ou objeto-relacional (português brasileiro) (ou ORM, do inglês: Object-relational mapping) é uma técnica de desenvolvimento utilizada para reduzir a impedância da programação orientada aos objetos utilizando bancos de dados relacionais. As tabelas do banco de dados são representadas através de classes e os registros de cada tabela são representados como instâncias das classes correspondentes.
Com esta técnica, o programador não precisa se preocupar com os comandos em linguagem SQL; ele irá usar uma interface de programação simples que faz todo o trabalho de persistência.(Wikipedia)
Vamos entender o problema
Você, que já programa em Delphi, me responda: quantas vezes escreveu os seguintes códigos?
- insert into … values (….)
- update …. set … where …
- delete from … where …
Já perdeu as contas não é mesmo?!? 🙂
Aqui mesmo neste blog, já coloquei um exemplo de DAO e apesar do ganho, ainda tive que fazer os comandos SQL na mão.
Sem contar a dependência (ou diríamos, o forte acoplamento?) exagerada dos componentes de conexão (Dbexpress, Ibx, Uib…). Imagine a seguinte situação: desenvolver toda uma aplicação baseada num determinado conjunto de componentes e na atualização para uma nova ide Delphi, descobrir que nesta última versão, este conjunto deixou de fazer parte das ferramentas que acompanham o Delphi ou até mesmo deixou de ser compatível com a nova versão(É só uma suposição, ok? Mas quem garante que isso não ocorra algum dia? :)).
É melhor prevenir do que remediar. Sendo assim, o ideal seria tornar mais abstrata a forma de acesso ao banco de dados, sem depender tanto de um componente específico de acesso. Caso seja necessário trocar, bastariam alguns ajustes e pronto! Acredite, eu sei do que eu estou falando. Lembra do Bde?!?
Mas aí vem a pergunta:
Como eu faço isso???
Bem, existem dois caminhos:
- Buscar algum ORM já existente;
- Desenvolver o seu próprio.
Vou logo adiantando, existem alguns bons frameworks, como por exemplo, o Aurelius (Comercial) e DORM (free). Ótimas funções e bom desempenho.
Aí, surge alguns questionamentos?
- Mas até quando iremos ficar no escuridão, dependendo de terceiros para executar nosso trabalho?
- Por outro lado, já que existe algo assim, por que então reinventar a roda?
- Mesmo utilizando algo existente, porque não construir um protótipo e assim ganhar em conhecimento?
Não sei você, mas a ideia de depender de terceiros não me deixa nem um pouco à vontade. Como eu já disse aqui no blog, nem sempre é possível deixar de usar componentes de terceiros (utilizo e muito componentes ACBR e JVCL), mas quando existe a alternativa de diminuir essa dependência, porque não?!
Portanto, faca nos dentes, mente aberta e muita força de vontade.
Iniciando os trabalhos
Primeiro, crie um banco qualquer (Firebird). Depois crie uma tabela chamada Teste, como na imagem abaixo:
No Delphi, crie uma nova aplicação VCL e no formulário criado renomeie para frmMain, como abaixo:
Para o nosso projeto, iremos iniciar com a utilização do UIB para a manipulação da base. Futuramente, iremos incluir outro conjunto de acesso.
Como pôde ser visto, o nosso formulário tem um botão, um componente de acesso e uma transação. Os componentes Uib poderíam ser colocados em um datamodule, mas para os testes, a forma como foi colocada já resolve.
Configure o UibDatabase1:
- DatabaseName: Nome e Local do banco de dados;
- Params
- password=masterkey
- user_name=SYSDBA
- Connected: True
E o UibTransaaction1:
- DataBase: UibDatabase1
- DefaultAction: etmCommit
O que será necessário?
Bom, agora já temos acesso ao nosso banco, podemos partir para criação de fato das nossas classes.
Mas calma, antes porém, precisamos analisar e entender como iremos persistir os dados. Primeiro, devemos criar uma classe chamada TTeste (baseada no nome da nossa tabela):
[sourcecode language=”delphi”]
TTeste = class
private
public
property Id: Integer;
property Estado: string;
property Descricao: string;
property Data: TDateTime;
property Habitantes: Integer;
property RendaPerCapta: Currency;
end;
[/sourcecode]
Esta é a estrutura da classe, ainda sem os campos e setters. Numa inclusão, por exemplo, é necessário saber o nome da tabela que será afetada, os campos que compõem a tabela, os campos PK (chave primária), os tipos dos campos (se é campo inteiro, string, data, blob, etc.). Isso, levando-se em consideração que iremos criar um ORM básico, nada de coisa do outro mundo.
Pergunta – como iremos conseguir estes dados através da estrutura acima?
Resposta – através de alguns recursos interessantes que temos à nossa disposição no Delphi:
- RTTI – Runtime Type Information (frequentemente abreviado para RTTI; Informação de Tipo [de Dado] em Tempo de Execução em inglês) é uma técnica disponível em algumas linguagens de programação e que consiste em manter informação sobre o tipo de dado de um objeto em memória durante o tempo de execução de um programa de computador. Algumas implementações limitam-se a manter somente a árvore de heranças da classe enquanto outras também incluem informações dos métodos do objeto e seus atributos. Wikipedia
- Generics
- Padrão Singleton
- Interfaces – Em algumas linguagens de programação, o termo interface (ou protocolo) é uma referência à característica que permite a construção de interfaces que isolam do mundo exterior os detalhes de implementação de um componente de software. WikiPedia
Veremos isso na prática nos próximos artigos da série. Até lá!
Muito bom o artigo, parabéns.
Aguardo a continuação.
voute seguir apartir da semana que vem, parece ter uma boa didatica…
Forte Abraço
Alex
Boa tarde tudo bem estou em uma longa caminhada para atualizar um sistema legado, que faz acesso a alguns bancos de dados (4) Firebird e 1 SQL Server, estou usando o delphi community, consigo usar o Firedac para o FB e o ADO para o SQL server, gostaria de saber se com este tutorial consigo contemplar esses acessos, e praticamente, deixar de usar o data module com varios database, datasets, datasource etc