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