Olá, neste artigo iremos apreender uma, dentre várias, forma de criar um acesso genérico a bancos de dados. Existem inúmeras formas de ser implementada esta solução de acesso genérico, esta que irei mostrar é a forma que utilizo há alguns anos e é a que estou mais familiarizado. Então vamos ver como vai funcionar.
Iremos criar um projeto de DLL no Visual Basic 2010 Express contendo uma classe mãe, chamada de clsDatabase, que deverá ser herdada pelas filhas, parar isso iremos incluir na declaração da classe a palavra MustInherit. Com isso, estamos dizendo que esta classe obrigatoriamente deve ser herdada por outra e não pode ser instanciada.
Como iremos utilizar diferentes bancos de dados, cada um possui algumas particulares em relação ao nome dos tipos de dados, por exemplo: os dados do tipo data e hora no postgres é Timestamp, no MySql é DateTime e no Access é DBTimeStamp. Para sanar essas diferenças de nomenclatura, iremos criar duas enumerações, uma com o nome dos bancos de dados suportados e outra com os tipos de dados. Neste nosso artigo, irei utilizar três bancos de dados: Access, MySql e PostGres. Você pode adicionar mais de acordo com sua necessidade.
Public Enum BaseDeDados
Access
MySql
Postgres
End Enum
Public Enum TipoDeDados
Booleano
Real
Data
Hora
DataHora
Texto
TextoLongo
Caracter
Longo
Inteiro
Imagem
Moeda
Duplo
End Enum
Precisamos criar variáveis que irão guardar as informações de conexão com o banco de dados.
Protected Shared dbServer As String
Protected Shared dbBaseNome As String
Protected Shared dbUser As String
Protected Shared dbPassword As String
Protected Shared dbBase As BaseDeDados
Protected Shared dbSegurancaOuSchema As String
As variáveis servem para guardar as respectivas informações: endereço do servidor onde está o banco de dados; nome da base de dados; usuário do banco de dados; senha do banco de dados; qual o SGBD que está sendo utilizado e a ultima variável serve para guardar o arquivo de segurança para bancos de dados access (se houver este arquivo) ou para guardar o schema da base de dados quando for utilizado o Postgres.
A seguir criaremos a variável que irá se conectar com o banco, uma variável para controlar transação e uma variável para guardar mensagens que possam retornar do banco.
Protected Shared dbConexao As IDbConnection
Protected Shared dbTransacao As IDbTransaction
Protected Shared dbMensagem As String = String.Empty
A seguir iremos criar uma variável que receberá a classe filha correspondente ao banco utilizado.
Private Shared filho As clsDatabase
Criaremos duas propriedades, uma para acessar a mensagem de retorno do banco e outra para informarmos qual o banco de dados que será utilizado.
Public Shared ReadOnly Property Mensagem() As String
Get
Mensagem = dbMensagem
dbMensagem = String.Empty
End Get
End Property
Public Shared Property BancoDeDados() As BaseDeDados
Get
Return dbBase
End Get
Set(ByVal value As BaseDeDados)
dbBase = value
End Set
End Property
A seguir criaremos alguns métodos que devem ser obrigatoriamente implementados pelas classes filhas. Para isso iremos declará-los como MustOverride. Criaremos os seguintes métodos:
· Public MustOverride Function _AbreConexao() As Boolean – Método para abrir conexão com o banco de dados. Retorna true se conseguir ou false de não conseguir abrir comunicação.
· Public MustOverride Function _FechaConexao() As Boolean – Método para fechar a conexão com o banco de dados. Retorna true se conseguir ou false de não conseguir fechar a comunicação.
· Public MustOverride Function _getNewCommand() As IDbCommand – Método para obter uma nova variável de comando para o banco de dados selecionado.
· Public MustOverride Function _pegarResultSet(ByVal vComando As IDbCommand) As DataTable – Método que retorna o resultado de um comando SQL de Select.
· Public MustOverride Function _pegarMetaDados(ByVal vComando As IDbCommand) As DataTable – Método que retorna os informações sobre os campos de determinada tabela do banco de dados.
· Public MustOverride Sub _AdicionaParametro(ByVal pComando As IDbCommand, ByVal pNome As String, ByVal pValor As Object, Optional ByVal pTipo As TipoDeDados = -1, Optional ByVal pDirecao As System.Data.ParameterDirection = ParameterDirection.Input, Optional ByVal pTamanho As Integer = 0, Optional ByVal pSourceColumn As String = "") – Método que adiciona um parâmetro a um comando que irá utilizar Stored Procedures.
· Public MustOverride Function _getLastInsertId(Optional ByVal pTableName As String = "") As Integer – Método que retorna o último id inserido no banco.
Repare que todas os métodos começam com o caractere “underline” ( _ ). Isso porque teremos métodos implementados pela classe mãe com os mesmos nomes, mas sem o underline no início. Esses métodos estão listados abaixo:
Public Shared Function AbreConexao() As Boolean
Return filho._AbreConexao
End Function
Public Shared Function FechaConexao() As Boolean
Return filho._FechaConexao
End Function
Public Shared Function getNewCommand() As IDbCommand
Return filho._getNewCommand
End Function
Public Shared Function pegarResultSet(ByVal vComando As IDbCommand) As DataTable
Return filho._pegarResultSet(vComando)
End Function
Public Shared Function pegarMetaDados(ByVal vComando As IDbCommand) As DataTable
Return filho._pegarMetaDados(vComando)
End Function
Public Shared Sub AdicionaParametro(ByVal pComando As IDbCommand, ByVal pNome As String, ByVal pValor As Object, Optional ByVal pTipo As TipoDeDados = -1, Optional ByVal pDirecao As System.Data.ParameterDirection = ParameterDirection.Input, Optional ByVal pTamanho As Integer = 0, Optional ByVal pSourceColumn As String = "")
filho._AdicionaParametro(pComando, pNome, pValor, pTipo, pDirecao, pTamanho, pSourceColumn)
End Sub
Public Shared Function getLastInsertId(Optional ByVal pTableName As String = "") As Integer
Return filho._getLastInsertId(pTableName)
End Function
Criaremos um método que irá servir para setar as configurações da base de dados.
Public Shared Sub setConfiguracoes(ByVal pBase As BaseDeDados, ByVal pServidor As String, ByVal pBanco As String, ByVal pUsuario As String, ByVal pSenha As String, Optional ByVal pSegurancaOuSchema As String = "")
dbBase = pBase
dbServer = pServidor
dbBaseNome = pBanco
dbUser = pUsuario
dbPassword = pSenha
dbSegurancaOuSchema = pSegurancaOuSchema
Select Case pBase
Case BaseDeDados.Access
filho = New clsAccess
Case BaseDeDados.MySql
filho = New clsMysql
Case BaseDeDados.Postgres
filho = New clsPostgres
End Select
End Sub
Este método possui os seguintes parâmetros, respectivamente: qual banco de dados será utilizado; o endereço do servidor; o nome da base de dados; o usuário de conexão do banco de dados; a senha de conexão do banco de dados e, opcionalmente, o local do arquivo de segurança (Access, se houver) ou o schema da base de dados (Postgres). Dentro do método, é verificado qual banco de dados será utilizado e a variável filho receberá a classe filha respectiva.
Criaremos um método que retornará a conexão atual com o banco de dados.
Public Shared Function GetConexao() As IDbConnection
Return dbConexao
End Function
Criaremos um método genérico de recuperação um único valor do banco de dados. Este método é útil quando se deseja obter um único valor de um único atributo de uma tabela da base de dados.
Public Shared Function recuperaValor(ByVal pComando As IDbCommand) As Object
recuperaValor = Nothing
If dbConexao.State = ConnectionState.Open Then
pComando.Connection = dbConexao
Try
recuperaValor = pComando.ExecuteScalar()
Catch ex As Exception
dbMensagem = ex.Message
recuperaValor = 0
End Try
End If
End Function
Outro método genérico a ser criado é o que executará ações no banco de dados que não retornem dados, como atualizações e exclusões.
Public Shared Function ExecutaComando(ByVal pComando As IDbCommand) As Long
Dim Continua As Boolean = True
If dbTransacao Is Nothing Then
Else
pComando.Transaction = dbTransacao
End If
If Not dbConexao.State = ConnectionState.Open Then
Continua = False
End If
If Continua Then
pComando.Connection = dbConexao
Try
ExecutaComando = pComando.ExecuteNonQuery()
Catch ex As Exception
dbMensagem = ex.Message
ExecutaComando = -1
End Try
Else
dbMensagem = "Conexão com a base de dados foi perdida."
ExecutaComando = -1
End If
End Function
E para finalizar nossa classe, iremos criar os métodos que controlarão as transações no banco de dados. Serão três métodos, um para iniciar a transação, outro para cancelar a transação e um terceiro para concluir a transação.
Public Shared Function IniciarTransacao() As Boolean
IniciarTransacao = True
If dbConexao.State = ConnectionState.Open Then
Try
dbTransacao = dbConexao.BeginTransaction()
Catch ex As Exception
dbMensagem = ex.Message
IniciarTransacao = False
End Try
Else
dbMensagem = "Falha na Base de Dados. Conexão não está aberta."
IniciarTransacao = False
End If
End Function
Public Shared Sub CancelarTransacao()
Try
dbTransacao.Rollback()
Catch ex As Exception
'não faz nada
dbMensagem = ex.Message
End Try
dbTransacao = Nothing
End Sub
Public Shared Function ConcluirTransacao() As Boolean
ConcluirTransacao = True
Try
dbTransacao.Commit()
Catch ex As Exception
ConcluirTransacao = False
Try
dbTransacao.Rollback()
dbMensagem = ex.Message
Catch ex2 As Exception
dbMensagem = ex2.Message
End Try
End Try
dbTransacao = Nothing
End Function
Com isso, nossa classe mãe está pronta. Em nosso próximo artigo, irei mostrar como construir as classes filhas para cada banco de dados de maneira separada.
Qualquer dúvida é só mandar um e-mail: domingosjunior87@gmail.com