VB .NET - Login com Fluent NHibernate, NHibernate 4.0 e PostGreSql - I


Este artigo mostra como usar o Fluent NHibernate e o NHibernate 4.0 para criar uma aplicação que realiza o login e faz o registro de um novo usuário no banco de dados PostgreSQL mostrando também como realizar as operações CRUD de manutenção dos usuários usando o padrão Repository.

Na seção  NHibernate - Macoratti.net você vai encontrar muitos artigos que eu já escrevi mostrando como usar os recursos do NHibernate.

Se você já chegou a usar o NHibernate e não conhece o Fluent NHibernate deve saber que gerar os arquivos de mapeamento (.hbm) dá muito trabalho e que é uma tarefa  que esta sujeita a erros.

Pois se esse isso era um quesito que o desmotivava a usar o NHibernate fique sabendo que agora você não tem mais essa desculpa.

O Fluent NHibernate chegou (a um bom tempo por sinal) para auxiliar a realização dos mapeamentos das suas entidades com o seu banco de dados. Com ele podemos realizar o mapeamento via código sem ter que usar os arquivos .hbm.

Apenas para comparar veja abaixo um exemplo de um arquivo de mapeamento .hbm gerado e sua contrapartida usando o Fluent NHibernate:       

(fonte: https://github.com/jagregory/fluent-nhibernate/wiki/Getting-started)

<?xml version="1.0" encoding="utf-8" ?>  
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  
  namespace="QuickStart" assembly="QuickStart">  
  <class name="Cat" table="Cat">  
    <id name="Id">  
      <generator class="identity" />  
    </id>  
    <property name="Name">  
      <column name="Name" length="16" not-null="true" />  
    </property>  
    <property name="Sex" />  
    <many-to-one name="Mate" />  
    <bag name="Kittens">  
      <key column="mother_id" />  
      <one-to-many class="Cat" />  
    </bag>  
  </class>  
</hibernate-mapping>

 

public class CatMap : ClassMap<Cat>
{
  public CatMap()
  {
    Id(x => x.Id);
    Map(x => x.Name)
      .Length(16)
      .Not.Nullable();
    Map(x => x.Sex);
    References(x => x.Mate);
    HasMany(x => x.Kittens);
  }
}

 

Arquivo XML .hbm código Fluent NHibernate equivalente

O Fluent NHibernate pode ser baixado no seguinte link:  http://www.fluentnhibernate.org/

Neste artigo eu vou criar um projeto Windows Forms usando a linguagem VB.NET e usando o NHibernate e Fluent NHibernate criar um formulário de login e registro de usuários para acessar um banco de dados PostgreSQL.

Recursos usados

Objetivos

Aprendizado

Criando o banco de dados e a tabela no PosgreSQL

Para criar o banco de dados e a tabela vamos usar o pgAdmin III (deve ser compatível com a versão do PostgreSQL que você usar).

Quando você abrir o pgAdmin verá seguinte janela:

Na janela à esquerda temos as conexões com o servidor de banco de dados. Inicialmente temos uma conexão padrão.

Durante a instalação o PostGreSQL já configurou o acesso ao nosso servidor local.

Clique duas vezes sobre o item PostGreSQL 9.3 (localhost:5432) para abrir a janela de conexão como servidor e informar a senha que você definiu durante a instalação para acessar o PostgreSQL.

Se você clicar em (+) da opção Databases verá que já existe um banco de dados definido como Postgresql que foi criado automaticamente na instalação. Esse banco de dados não será utilizado e não pode ser excluído por se tratar de um banco utilizado para administração do Postgresql.

Vamos criar nosso banco de dados. Clique com o botão direito do rato em cima de Databases e escolha a opção New Database:

Na janela New DataBase informe o nome do banco de dados - Cadastro e define o Owner como sendo o usuário postgres:

Agora vamos criar a nossa tabela usuarios que deverá possuir a seguinte estrutura:

Para isso faça o seguinte:

  1. Selecione o objeto Tables()
  2. Clique no menu SQL
  3. Na janela do editor SQL digite a instrução SQL Create Table conforme abaixo para criar a tabela usuarios
create table usuarios(
                id serial not null primary key,
                nome varchar(100),
                login varchar(50),
                senha varchar(50),
                status char(1)
                )               
  1. Clique no botão para executar a instrução e criar a tabela no banco de dados Cadastro.

Concluindo esta etapa você poderá ver a tabela usuarios e as coluna criadas no Object Browser.

Se clicar com o botão direito sobre a tabela verá um menu suspenso com diversas opções para gerenciar a tabela.

Clicando em View Data -> View Top 100 Rows será aberta a janela onde você poderá incluir e visualizar os dados na tabela conforme figura abaixo:

Criando a solução no VS 2013 Express Edition for Windows Desktop

Abra o Visual Studio 2013 Express for Windows Desktop e clique em New Project;

Selecione o template Visual Studio Solution e informe o nome ControleUsuarios e clique no botão OK;

Criamos uma solução vazia onde iremos agora incluir os nossos projetos.

No menu FILE clique em Add -> New Project;

A seguir selecione o template Class Library e informe o nome Repositorio e clique no botão OK;

No menu FILE clique em Add -> New Project;

Selecione o template Windows Forms Application e informe o nome Usuarios e clique no botão Add;

Temos agora uma solução contendo dois projetos:

Incluindo as referências ao NHibernate , Fluent NHibernate e ao provedor Npgsql

Vamos agora criar 2 pastas no projeto Repositorio.

Clique com o botão direito do mouse sobre o projeto e a seguir clique em Add -> New Folder e informe o nome Entidades.

Repita o procedimento acima e cria a pasta com o nome Mapeamento.

Vamos agora referenciar o NHibernate , o Fluent NHibernate e o provedor Npgsql para acessar o PostgreSQL usando o Nuget.

O papel do Nuget é justamente ser um gerenciador de bibliotecas de modo a garantir que todas as dll´s de um pacote estejam atualizadas com suas versões corretas evitando assim erros de referência em seus projetos.

No menu TOOLS clique em Library Package Manager -> Manage Nuget Packages for Solution;

Na janela - Manage Nuget Packages - digite NHibernate para localizar o pacote e a seguir clique no botão Install;

Clique no botão OK para instalar o pacote nos projetos da solução.

Selecione a seguir o pacote FluentNHibernate e clique no botão Install repetindo o procedimento feito:

Retorne a janela - Manage Nuget Packages - e digite Npgsql para localizar o pacote e a seguir clique no botão Install;

Ao final teremos as referências ao NHibernate, Fluent NHibernate e ao provedor Npgsql instalados em nossa solução e estamos prontos para criar o Repositório, as entidades e o mapeamento ORM.

Criando as Entidades, o Mapeamento com Fluent NHibernate

Vamos começar definindo a entidade Usuario na pasta Entidades. Clique com o botão direito do mouse sobre a pasta Entidades e a seguir selecione Add -> Class;

Informe o nome Usuario.vb e digite o código abaixo neste arquivo:

Public Class Usuario
    Public Overridable Property Id As Integer
    Public Overridable Property Nome As String
    Public Overridable Property Login As String
    Public Overridable Property Senha As String
    Public Overridable Property Status As Char         
End Class

E importante usar o modificador Overridable na definição das propriedades e atentar que cada uma deve estar relacionada com as colunas da tabela usuarios criada no PostgreSQL.

Agora vamos criar o mapeamento ORM usando o Fluent NHibernate. Clique com o botão direito sobre a pasta Mapeamento e selecione Add -> Class;

Informe o nome UsuarioMap e digite o código abaixo neste arquivo:

Imports FluentNHibernate.Mapping
Public Class UsuarioMap
    Inherits ClassMap(Of Usuario)
    Sub New()
        Id(Function(m) m.Id)
        Map(Function(m) m.Nome)
        Map(Function(m) m.Login)
        Map(Function(m) m.Senha)
        Map(Function(m) m.Status)
        Table("usuarios")
    End Sub
End Class

Neste código mapeamos as propriedades definidas na classe Usuario para os campos da tabela usuarios definido na propriedade Table do Fluente NHibernate.

Usamos aqui as expressões lambdas que são funções podem conter expressões e declarações que são usadas para criar delegates e árvores de expressões onde o tipo das variáveis não precisam ser declarados visto que elas usam métodos anônimos.

Para saber mais sobre expressões lambdas veja o meu artigo: .NET - Expressões Lambdas

Criando a SessionFactory e o Repositório

Vamos começar criando uma classe chamada SessionFactory que será responsável por disponibilizar uma session que representa o nosso contexto. Nesta classe iremos definir a string de conexão e a conexão com o banco de dados PostgreSQL.

No menu PROJECT clique em Add Class e informe o nome SessionFactory. Em seguida digite o código abaixo nesta classe:

Imports NHibernate
Imports FluentNHibernate.Cfg.Db
Imports FluentNHibernate.Cfg

Public Class SessionFactory

    Private Shared ConnectionString As String = "Server=localhost; Port=5432; User Id=postgres; Password=********; Database=cadastro"

    Private Shared session As ISessionFactory

    Public Shared Function CriarSession() As ISessionFactory
        If session IsNot Nothing Then
            Return session
        End If
        Dim configDB As IPersistenceConfigurer = PostgreSQLConfiguration.PostgreSQL82.ConnectionString(ConnectionString)

        Dim configMap = Fluently.Configure().Database(configDB).Mappings(Function(c) c.FluentMappings.AddFromAssemblyOf(Of UsuarioMap)())

        session = configMap.BuildSessionFactory()

        Return session
    End Function

    Public Shared Function AbrirSession() As ISession
        Return CriarSession().OpenSession()
    End Function

End Class

A classe SessionFactory possui métodos estáticos para criar e abrir uma sessão que representa o contexto e a conexão com o banco de dados PostgreSQL.

Após isso vamos criar o nosso repositório.

Nesse projeto iremos usar o padrão Repository e criar um repositório genérico onde iremos definir os métodos de acesso aos dados.

O que é o padrão Repository ?

Um repositório é essencialmente uma coleção de objetos de domínio em memória, e, com base nisso o padrão Repository permite realizar o isolamento entre a camada de acesso a dados (DAL) de sua aplicação e sua camada de apresentação (UI) e camada de negócios (BLL).

Ao utilizar o padrão Repository você pode realizar a persistência e a separação de interesses em seu código de acesso a dados visto que ele encapsula a lógica necessária para persistir os objetos do seu domínio na sua fonte de armazenamento de dados.

Em suma, você pode usar o padrão Repository para desacoplar o modelo de domínio do código de acesso a dados.

Martin Fowler afirma: "O padrão  Repository faz a mediação entre o domínio e as camadas de mapeamento de dados, agindo como uma coleção de objetos de domínio em memória.....Conceitualmente, um repositório encapsula o conjunto de objetos persistidos em um armazenamento de dados e as operações realizadas sobre eles, fornecendo uma visão mais orientada a objetos da camada de persistência.....e também da suporte ao objetivo de alcançar uma separação limpa e uma forma de dependência entre o domínio e as camadas de mapeamento de dados." (http://martinfowler.com/eaaCatalog/repository.html)

Em uma das implementações do padrão repositório podemos começar definindo uma interface que atuará como a nossa fachada de acesso aos dados. Vamos criar então uma interface chamada IUsuarioCrud.

Estando no  projeto Repositorio clique no  menu PROJECT clique em Add New Item e selecione o template Interface informando o nome IUsuarioCrud e defina o código a seguir neste arquivo:

Public Interface IUsuarioCrud(Of T)
    Sub Inserir(entidade As T)
    Sub Alterar(entidade As T)
    Sub Excluir(entidade As T)
    Function BuscarPorId(Id As Integer) As T
    Function Consultar() As IList(Of T)
End Interface

Temos assim uma interface definindo os métodos CRUD que deverá ser implementada por uma classe concreta que iremos criar e que se chamará Repositorio.vb.

Estando no  projeto Repositorio clique no  menu PROJECT clique em Add Class e selecione o template Class informando o nome Repositorio e a seguir defina o código abaixo:

Imports NHibernate
Imports System.Linq
Imports NHibernate.Linq
Imports System.Linq.Expressions
Public Class Repositorio(Of T As Class)
    Implements IUsuarioCrud(Of T)
    Public Sub Alterar(entidade As T) Implements IUsuarioCrud(Of T).Alterar
        Using session As ISession = SessionFactory.AbrirSession()
            Using transacao As ITransaction = session.BeginTransaction()
                Try
                    session.Update(entidade)
                    transacao.Commit()
                Catch ex As Exception
                    If Not transacao.WasCommitted Then
                        transacao.Rollback()
                    End If
                    Throw New Exception("Erro ao Alterar Cliente : " + ex.Message)
                End Try
            End Using
        End Using
    End Sub

    Public Sub Excluir(entidade As T) Implements IUsuarioCrud(Of T).Excluir
        Using session As ISession = SessionFactory.AbrirSession()
            Using transacao As ITransaction = session.BeginTransaction()
                Try
                    session.Delete(entidade)
                    transacao.Commit()
                Catch ex As Exception
                    If Not transacao.WasCommitted Then
                        transacao.Rollback()
                    End If
                    Throw New Exception("Erro ao Excluir Cliente : " + ex.Message)
                End Try
            End Using
        End Using
    End Sub
    Public Sub Inserir(entidade As T) Implements IUsuarioCrud(Of T).Inserir
        Using session As ISession = SessionFactory.AbrirSession()
            Using transacao As ITransaction = session.BeginTransaction()
                Try
                    session.Save(entidade)
                    transacao.Commit()
                Catch ex As Exception
                    If Not transacao.WasCommitted Then
                        transacao.Rollback()
                    End If
                    Throw New Exception("Erro ao inserir Cliente : " + ex.Message)
                End Try
            End Using
        End Using
    End Sub
    Public Function BuscarPorId(Id As Integer) As T Implements IUsuarioCrud(Of T).BuscarPorId
        Using session As ISession = SessionFactory.AbrirSession()
            Return session.Get(Of T)(Id)
        End Using
    End Function
    Public Function Consultar() As IList(Of T) Implements IUsuarioCrud(Of T).Consultar
        Using session As ISession = SessionFactory.AbrirSession()
            Return (From c In session.Query(Of T)() Select c).ToList()
        End Using
    End Function
End Class

Vemos no código a implementação dos métodos CRUD da interface IUsuarioCrud.

Agora só falta definir uma classe para que possamos usar o repositório genérico.

No menu PROJECT clique em Add -> Class e informe o nome UsuarioRepositorio digitando o código abaixo neste classe:

Imports NHibernate
Imports System.Linq
Imports NHibernate.Linq
Public Class UsuarioRepositorio
    Inherits Repositorio(Of Usuario)
    Public Function ValidarLogin(login As String) As Boolean
        Using session As ISession = SessionFactory.AbrirSession()
            Return (From e In session.Query(Of Usuario)() Where e.Login.Equals(login) Select e).Count > 0
        End Using
    End Function
    Public Function ValidarAcesso(login As String, senha As String) As Boolean
        Using session As ISession = SessionFactory.AbrirSession()
            Return (From e In session.Query(Of Usuario)() Where e.Login.Equals(login) AndAlso e.Senha.Equals(senha) Select e).Count > 0
        End Using
    End Function
End Class

A nossa classe UsuarioRepositorio herda da classe Repositorio e inclui dois métodos usando consultas LINQ:

Estamos prontos para usar o nosso repositório para acessar e persistir informações no PostgreSQL usando a classe UsuarioRepositorio.

Na continuação deste artigo irei mostrar a criação dos formulários de login e registro no projeto Windows Forms e mostrar como usar o nosso repositório para implementar o login e o registro de um novo usuário.

João 5:24 Em verdade, em verdade vos digo que quem ouve a minha palavra, e crê naquele que me enviou, tem a vida eterna e não entra em juízo, mas já passou da morte para a vida.

Veja os Destaques e novidades do SUPER DVD Visual Basic (sempre atualizado) : clique e confira !

Quer migrar para o VB .NET ?

Quer aprender C# ??

Quer aprender os conceitos da Programação Orientada a objetos ?

Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ?

 

             Gostou ?   Compartilhe no Facebook   Compartilhe no Twitter
 

Referências:


José Carlos Macoratti