O NeoMatrix Tech está de casa nova!

Você deverá ser redirecionado em 6 segundos. Se não, visite:
http://www.leonelfraga.com/neomatrixtech
e atualize seus favoritos.

Aviso IMPORTANTÍSSIMO!

Aviso aos navegantes:

O NeoMatrix Tech mudou de casa!!!

A partir de agora, acessem pelo novo endereço:

http://www.leonelfraga.com/neomatrixtech

Ué... mas é só o domínio mudou de lugar?

R: Na verdade, não é bem assim hehe. Este domínio que você acessa agora aponta para um blog hospedado no Blogger, enquanto no novo, aponta para um blog na plataforma Wordpress, hospedagem própria, muito mais rápida e com um layout mais agradável de ler ;)

Não vou fechar este domínio igual ao que eu fiz com o NM Light (que já está 100% na nova plataforma). Talvez beeeeeeem depois eu faça isso.

Todos os posts daqui se encontram lá, e novos posts serão colocados somente no novo endereço.
A única coisa que não consegui importar foram os comentários. Mas em breve vai ter um post contando sobre a epopéia que foi migrar o NeoMatrix Tech!

Somente vou fechar a área de comentários daqui. Caso queiram comentar, favor ver o post correspondente no "Novo NeoMatrix Tech" e comentem por lá. É bem melhor! (pena que os permalinks "amigáveis para SEO" não funcionam lá, dá erro 404 e não consigo fazer a configuração funcionar. E olha que eu já vi vários artigos falando desse assunto :( ).

Quem assina o feed, já está lendo o conteúdo do novo NeoMatrix Tech!

sábado, 29 de março de 2008

Framework de Abstração para Bancos de Dados - Parte 1 - Introdução

E aí galera!!! Como vocês estão?
 
Como eu havia dito em meu último post no meu site do Multiply, irei publicar aqui uma série de artigos falando (e dando exemplos, lógico!) de um framework (sim, acho que poderei chamá-lo assim hehe) que que construí para abstrair operações em banco de dados em bibliotecas de classe, onde ele é utilizado. Ainda não tenho um nome para ele, lá onde eu trabalho ele geralmente é chamado de "Classe de Conexão do Leonel", pura e simplesmente :-)

Ele é construído com base no .NET Framework 2.0 e suporta bancos de dados Firebird (usando o .NET Firebird Client), SQL Server (usando SQL Client), Oracle (usando Oracle Client da MS), bancos de dados acessíveis via OLE DB e ODBC, ou seja, qualquer banco de dados, sendo que alguns com provider nativo, como o Firebird e o SQL Server.
Como assim abstrair operações de bancos de dados?

Durante o desenvolvimento de bibliotecas de classe, geralmente precisamos fazer acesso a um banco de dados para consultar, inserir e atualizar os registros dentro dele. Para isso, no .NET utilizamos as classes presentes no ADO.NET e dos diversos providers que são suportados por ele.

Cada provider do ADO.NET possui diversas classes que representam os objetos que fazem o acesso ao banco, como Connection, DataReader, DataAdapter, Transaction, entre outros.
Estes objetos que citei são interfaces dentro do ADO.NET, como o Connection que é a interface IDBConnection do ADO.NET. Cada provider implementa estas interfaces. Você já reparou que os providers tem os mesmos objetos, só mudando o nome? Sim, é isso mesmo! Se você aprende a utilizar um, pode utilizar todos. Claro que cada um tem as suas particularidades, mas vamos ficar com o que tem no padrão.

Por exemplo, se quisermos executar uma instrução INSERT no SQL Server e no Firebird, teremos o seguinte:

SQL Server:

   1: public bool Inserir()
   2: {
   3:     bool retorno = false;
   4:     SQLConnection cn = new SQLConnection(this.MinhaStringDeConexao);
   5:     SQLCommand cd = new SQLCommand();
   6:     try
   7:     {
   8:         cd.Connection = cn;
   9:         cn.Open();
  10:         cd.CommandText = "insert into MINHATABELA values (1,2,3)";
  11:         cd.ExecuteNonQuery();
  12:     }
  13:     catch
  14:     {
  15:         retorno = false;
  16:     }
  17:     finally
  18:     {
  19:         cn.Close();
  20:         cn.Dispose();
  21:         cd.Dispose();
  22:     }
  23:     return retorno;
  24: }


Firebird:

   1: public bool Inserir()
   2: {
   3:         bool retorno = false;
   4:         FbConnection cn = new FbConnection(this.MinhaStringDeConexao);
   5:         FbCommand cd = new FbCommand();
   6:     try
   7:     {
   8:         cd.Connection = cn;
   9:         cn.Open();
  10:         cd.CommandText = "insert into MINHATABELA values (1,2,3)";
  11:         cd.ExecuteNonQuery();
  12:     }
  13:     catch
  14:     {
  15:         retorno = false;
  16:     }
  17:     finally
  18:     {
  19:         cn.Close();
  20:         cn.Dispose();
  21:         cd.Dispose();
  22:     }
  23:     return retorno;
  24: }


Viu como é a mesma coisa? Só muda os nomes dos objetos, do ponto de vista da nossa codificação.

Mas convenhamos que ficar instanciando estes objetos em cada método em que temos que executar um comando SQL é um pé no saco. Lembrando ainda que sempre temos que fechar as conexões que abrimos e desalocar da memória os objetos que instanciamos! Ficar repetindo estes códigos (instancia pra lá, fecha conexão pra cá, finaliza pra cá...) leva tempo, e como a velha máxima para os profissionais de TI de que "tempo é dinheiro" é bem válida, temos que economizar tempo para entregar rapidamente o projeto, senão, já viu!

A minha proposta com este framework de abstração é justamente "pular" esta parte de instanciar e destruir objetos de banco de dados. O controle da conexão e dos objetos de BD é feito única e exclusivamente dentro da classe principal do framework; nas nossas classes, iremos nos preocupar unicamente com as regras de negócio.

Ele é composto de uma classe mais algumas enumerações auxiliares que visa a execução de comandos SQL e recuperação de valores em banco de dados baseado em instruções select que retornam datatables ou object. Dentro desta classe há métodos e propriedades que abstraem todos os objetos mais utilizados de acesso a dados, portanto, não é necessário conhecer os objetos especificos de cada provider, apenas é necessário fazer a referência do mesmo no seu projeto.

Um pouco de história - Como foi o "pontapé" inicial:

No ano de 2005, fiz um curso de ASP.NET com C#, e nele aprendi a fazer páginas ASP.NET, trabalhar com bibliotecas de classe e acessar banco de dados.
No curso teve uma aula em que o professor falou sobre herança. Na superclasse ficavam os objetos de conexão a banco de dados, como o Connection e tinha algums métodos para executar comando SQL, como o Inserir() que coloquei como exemplo. Na subclasse, tinha uma rotina que montava um comando SQL e que chamava esse método da superclasse para executar o comando SQL. A partir daí, comecei a desenvolver os projetos onde eu trabalho seguindo esta metodologia: em uma classe ficavam os métodos que executavam comandos SQL, e nas subclasses tinham as regras de negócio. Nas páginas ASPX ou nos formulários Windows não tinha código de banco de dados, somente chamadas às classes contidas na biblioteca de regras de negócio.

Inicialmente, construí a minha "Classe de Conexão" somente com os objetos do Firebird, que é o banco de dados que utilizamos nos projetos. Esta classe tinha métodos para executar comandos que não retornam resultsets (como um INSERT ou um UPDATE), executar stored procedure, retornar resultsets nas formas de DataTable e FbDataReader e algumas propriedades para guardar a string de conexão, mensagens para o usuário, entre outras.

Projetos e mais projetos com o Firebird a classe ia evoluindo junto. Melhorias no tratamento de erros, novos métodos, otimização dos métodos existentes... muita coisa foi feita, mas ainda tinha um problema: era fortemente dependente do FireBird! Nos métodos das subclasses, para executar uma stored procedure, por exemplo, era necessário declarar cada FbParameter! E os DataReaders? Era necessária a utilização de vários FbDataReaders em várias partes do código!

Em um dos projetos em que eu trabalho, teve problema de lentidão entre outros. Além do servidor inadequado para a aplicação, ela não estava bem escrita, confesso. Revisei todo o código da mesma, e claro, fiz uma melhoria drástica na "Classe de Conexão": Objetos ESPECÍFICOS do FireBird ficam APENAS na "Classe de Conexão"! Nas subclasses, eu nem colocaria a cláusula using referente ao provider do mesmo. Reescrevi todos os métodos das classes para se adequarem ao novo formato (isso fora a migração do Framework 1.1 para o 2.0). Quem controla abertura e fechamento de conexão, e gerenciamento dos objetos de banco de dados instanciados é a Classe de Conexão. Resultado: código mais limpo e mais rápido também. Valeu muito a pena, embora tenha me dado um estresse danado :-)

Um dia, um colega de serviço, o famoso Beto (como eu sempre digo - NÃO ESTOU ZUANDO, hehehe - , esse é O CARA!!!), me propôs um desafio: "duvido você construir uma classe que acesse vários bancos de dados", mais ou menos assim. Dito e feito! Construí a classe que faz acesso a vários bancos de dados! Os providers específicos de cada BD ficam somente na classe de conexão, e as referências ao provider na cláusula using também. Fora da classe, não é utilizado NENHUM objeto específico de banco de dados!

A versão atual do framework roda em projetos com Oracle, Firebird e SQL Server sem nenhuma mudança no código. É a mesmíssima classe nestes projetos.

A mágica? A Orientação a Objetos (POO) é a mágica! Se vocês olharem o código da classe que irei disponibilizar, eu uso e abuso das interfaces das quais as classes do provider implementam. Conforme o provider a ser utilizado, eu atribuo o objeto específico ao genérico que eu declarei e executo a funcionalidade. Quer um exemplo?
Supomos que exista uma interface ISerHumano e duas classes THomem e TMulher que o implementam. Então, é possível fazer o seguinte:

   1: public interface ISerHumano
   2: {
   3:     public void Falar();
   4: }
   5:  
   6: public partial class THomem : ISerHumano
   7: {
   8:     public void Falar()
   9:     {
  10:         this.AlgumaCoisa();
  11:     }
  12: }
  13:  
  14: public partial class TMulher : ISerHumano
  15: {
  16:     public void Falar()
  17:     {
  18:     this.OutraCoisa();
  19:     }
  20: }
  21:  
  22: public void Testar()
  23: {
  24:     ISerHumano pessoa1;
  25:     ISerHumano pessoa2;
  26:     pessoa1 = new THomem(); //Sim, é possível atribuir um objeto em um outro objeto de classe ou interface ascendente!
  27:     pessoa2 = new TMulher();
  28:     pessoa1.Falar(); // -> Irá executar o método implementado na classe THomem
  29:     pessoa2.Falar(); // -> Irá executar o método implementado na classe TMulher
  30: }


Sim, embora o objeto pessoa1 seja declarado como a interface, quando atribuímos-lhe uma instância de THomem, ao chamarmos o método Falar() será executado o método implementado na classe THomem, e quando atribuímos-lhe uma instância de TMulher, será executado o método implementado na classe TMulher.
Com isso, o retorno dos métodos são dos tipos básicos (ou das interfaces) da linguagem ou do namespace System.Data, ou seja, booleanos, inteiros, objects, datatables. Nenhum objeto específico do BD é retornado por alguma função deste framework.

Ele é utilizado em bibliotecas de classes, portanto, forçando o desenvolvimento em camadas: um projeto de apresentação (um site ASP.NET ou um Formulário Windows) e pelo menos uma biblioteca de classes que irá conter as regras do negócio. O foco deste framework é esta biblioteca de classes. Ele foi programado para ser utilizado como a superclasse principal das classes que manipulam os dados no banco de dados. Portanto, iremos utilizar largamente o conceito de herança!

Para "forçar" o programador a não utilizar os objetos de execução dos comandos SQL na camada de apresentação, todos os métodos que pedem SQL como parâmetro são declarados como protected. Portanto, é necessário uma subclasse para utilizá-los; não é possível instanciar diretamente a classe de conexão.

O download da classe de conexão poderá ser feito aqui: Página de Suporte do NeoMatrix Tech
Classe de Conexão (versão 1) (7 KiB)


Nos próximos artigos, desenvolveremos uma aplicação de cadastro utilizando este framework.

Então, até lá e um forte abraço a todos!

Leia o restante deste post...

segunda-feira, 17 de março de 2008

"Inauguração" do NeoMatrix Tech

Ae Galera! E aí, como vão, tudo beleza?

Então... este é o meu novo blog. Estou "aposentando" o blog do Multiply, mas não vou excluí-lo não, pois lá tem alguns artigos, vídeos e fotos que não vou migrar.

Criei um aqui por ser mais simples, mais customizável, esse tipo de coisa. Lá eu ainda vou terminar a série de artigos sobre geração de arquivos EDI usando C# e Orientação a Objetos; a próxima série de artigos que eu tenho em mente, que será um "framework" de execução de instruções SQL (um "motor" SQL, que pode ser utilizado com vários SGBDs e utilizado geralmente em biblioteca de classe - um modelo de desenvolvimento que eu utilizo na empresa onde trabalho) será publicado neste novo blog.

Para vídeos, criei uma conta no youtube e vou colocar lá; já as fotos, pretendo usar o Flickr, do Yahoo Picasa, do Google, se vcs puderem indicar algum serviço semelhante, vou analisar :-)

Por que o nome NeoMatrix Tech?

O nome "NeoMatrix" vocês podem deduzir que veio da trilogia Matrix, o que está absolutamente correto! Mas antes de batizar o blog com esse nome, esta é a razão social da minha empresa (trabalho como PJ), que é a NeoMatrix Soluções em Processamento de Dados Ltda, escolhi este nome pois gosto da trilogia.
Poderia ter chamado também de "LeoMatrix", que começa com as iniciais do meu primeiro nome. Mas "Neo" tem sonoridade melhor, acho!

Agora quanto ao o "sobrenome" "Tech", é porque este é um blog que tratará majoritariamente de tecnologia, seja programação, comentários sobre aparelhos, comentários sobre as notícias de tecnologia e outras coisas.

Mas não é só sobre isso que eu vou falar aqui não... Ele será também um canal onde No NeoMatrix Light, a outra "face" do meu portal irei comentar (e vocês também poderão e devem comentar, claro!) sobre coisas do cotidiano que nada ou pouco tem a ver com tecnologia, sejam séries de TV, política, fatos do meu dia-a-dia, etc.

E por falar em dia-a-dia, hoje o meu "N95 The King" foi para a assistência técnica... Um mês sem o bichão aqui (TOMARA que seja só um mês, viu Nokia!).
Ele apresentava um defeito intermitente na câmera principal, que tinha horas que não aparecia nenhuma imagem, ele não abre o foco nem a pau.
Esses dias foi pro espaço de vez, depois de um "bumba no caneco" (reiniciar o micro qualquer aparelho pelas vias normais, por exemplo - aguardem post sobre esses e outros "termos" hehehe) por que a câmera estava desfocada.
O resto funciona perfeitamente. Esse era um defeito que ocorria desde que eu comprei, mas não liguei para isso, agora que deu chabu de vez... paciência!

Só porque eu queria filmar decentemente o show do Ozzy Osbourne, que eu vou!!! Agora, vou ter que levar a minha valente câmera digital Canon Powershoot A410 para as fotos e os vídeos com o meu outro valente celular LG Black Safira. Ah, e seguem os links do meu Multiply e do meu canal no YouTube: http://www.youtube.com/leonelfraga http://leonelfraga.multiply.com/

Enfim, é isso ae! Um abraço a todos e até a próxima!

Leia o restante deste post...

Sobre o NeoMatrix Tech

Meu blog para assuntos profissionais, ligado com tecnologia.
Dicas de programação (grande parte de C# e ASP.NET, mas não limitado a essa plataforma :-) ), dicas de utilitários, análises de equipamentos e serviços, resenhas sobre sites que eu visito, relacionados com tecnologia, opinião sobre mercado de trabalho, metodologias de desenvolvimento, comportamento no mundo tecnológico...

NeoMatrix Light

  © Blogger templates ProBlogger Template by Ourblogtemplates.com 2008 - Editado e configurado por Leonel F.

Voltar ao TOPO