 C#
- Usando o NHibernate 2.1 com SharpDevelop 3.1 e MySQL/SQL Server
II
C#
- Usando o NHibernate 2.1 com SharpDevelop 3.1 e MySQL/SQL Server
II
|  | Neste artigo veremos como usar o NHibernate com SharpDevelop acessando o MySql e o SQL Server. | 
Se você esta chegando agora é bom se situar...
Na primeira parte deste artigo eu defini o nosso objetivo, defini os recursos que iríamos usar, criei o banco de dados e as tabelas no MySQL e no SQL Server, criei o projeto no SharpDevelop, defini as referências usadas no projeto, a classe do nosso domínio e o arquivo de configuração para o NHibernate.
Nesta última parte do artigo vamos definir o arquivo de configuração da aplicação e realizar as operações usando os recursos do NHibernate.
Definindo o arquivo de configuração da aplicação
Se você já criou aplicações na plataforma .NET com acesso a dados usando DataSets ou DataReaders deve estar familiarizado com o conceito de armazenar a string de conexão em um arquivo de configuração App.Config ou Web.Config.
Pois para o NHibernate o conceito é o mesmo. Você tem que definir em um arquivo de configuração algumas informações que orientam o NHibernate quanto o banco de dados que esta sendo usado a string de conexão e outros detalhes.
Como estamos trabalhando com uma aplicação Windows Forms vamos criar um arquivo app.config.
Com o projeto aberto no SharpDevelop, no menu Projeto selecione -> Adicionar Novo Item;
Na janela Novo Arquivo selecione a Categoria Misc e em Modelos selecione App.Config File e clique Criar;
|  | 
A seguir defina no arquivo XML criado o seguinte conteúdo:
| <?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="hibernate-configuration" type="NHibernate.Cfg.ConfigurationSectionHandler, NHibernate" />
</configSections>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">
       NHibernate.Connection.DriverConnectionProvider
</property>
<property name="connection.driver_class">
    <!--NHibernate.Driver.SqlClientDriver-->
    NHibernate.Driver.MySqlDataDriver
</property>
<property name="connection.connection_string">
   <!--Server=.\SQLEXPRESS;database=AloMundo;Integrated Security=SSPI;-->
   Server=localhost;Database=alomundo;User ID=root;Password=gpxpst
</property>
<property name="dialect">
   <!--NHibernate.Dialect.MsSql2000Dialect	-->
   NHibernate.Dialect.MySQLDialect
</property>
<property name="show_sql">
   false
</property>
<property name="hbm2ddl.keywords">
   none
</property>
<property name="proxyfactory.factory_class">
   NHibernate.ByteCode.Castle.ProxyFactoryFactory, NHibernate.ByteCode.Castle
</property>
</session-factory>
</hibernate-configuration>
</configuration> | 
Lembrando que esta configuração vale para a versão 2.0 do NHiberante ou superior.
O arquivo pode parecer complicado mas na verdade ele apenas defini alguns parâmetros para a aplicação os quais são:
- <property name="connection.provider"> - define o provedor usado pelo NHibernate
NHibernate.Connection.DriverConnectionProvider
- <property name="connection.driver_class"> - define o driver usado para conexão com o banco de dados. Observe que temos dois valores: um que esta comentado e outro que esta ativo. Fizemos assim pois vamos usar dois banco de dados: O MySQL e o SQL Server logo para o banco de dados ativo usamos o driver correspondente.
<!--NHibernate.Driver.SqlClientDriver-->
NHibernate.Driver.MySqlDataDriver
- <property
name="connection.connection_string"> -
define a string de conexão com o banco de dados. Novamente temos
dois valores um para o SQL Server e outro para o MySQL.
<!--Server=.\SQLEXPRESS;database=AloMundo;Integrated
Security=SSPI;-->
Server=localhost;Database=alomundo;User
ID=root;Password=xxxxxx
- <property name="show_sql"> - Define
se os comandos SQL serão exibidos ou não.
false
<property name="proxyfactory.factory_class"> -
Define o proxy usado pelo NHibernate
NHibernate.ByteCode.Castle.ProxyFactoryFactory,
NHibernate.ByteCode.Castle
O NHibernate usa este arquivo para saber como tratar com o banco
de dados e como usá-lo.
Como eu já mencionei uma das grandes vantagens do NHibernate é poder abstrair os comandos SQL e a independência do banco de dados. Quando usamos ADO .NET temos todo um trabalho relacionado com a definição de objetos para conexão e persistência de dados bem como dos comandos SQL envolvidos.
Apenas para ilustrar, a figura abaixo mostra uma comparação de um exemplo de arquitetura usando a ADO .NET e o NHibernate.
|  | 
Pois bem, se com o NHibernate eu não tenho que escrever comandos SQL como tenho que fazer para realizar operações de persistência ?
O NHibernate utiliza as interface ISession, ITransaction e IQuery para realizar a interação e a persistência com o banco de dados, portanto para usar esses recursos do NHibernate temos que usar essas interfaces. Onde:
Vamos então definir uma aplicação Windows Forms bem simples onde iremos realizar operações de consulta e persistência de dados usando esses recursos.
Vamos definir uma pequena aplicação que realiza o controle de funcionários de uma empresa. Nela iremos realizar as seguintes operações: Consultar e exibir empregados, criar , atualizar e excluir empregados. Para isso defini no formulário padrão da aplicação a o seguinte leiaute para a interface:
|  | Controles usados : 
 | 
Todas as operações que iremos realizar devem usar a interface ISession e abrir uma sessão a partir da qual o NHibernate obtém as informações que definimos nos arquivos de configuração. Nosso primeiro passo será definir um método que usa a interface ISession. Eu vou fazer isso no próprio formulário da aplicação e não em uma camada separada como seria o correto pois quero focar em mostrar como usar esses recursos básicos do NHibernate e não estou preocupado com as boas práticas neste momento.
Definindo o código da aplicação
Então no próprio formulário vamos primeiro definir os namespaces que vamos usar na aplicação:
using
System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using NHibernate;
using NHibernate.Cfg;
using System.Reflection;
using MySql.Data.MySqlClient;
using MySql.Data;
A seguir vamos definir o método estático OpenSession que irá definir uma sessão para o NHibernate conforme o código abaixo:
| //define uma sessão
static ISession OpenSession()
{
	   if(factory == null)
	   {
		   try{
		      Configuration c = new Configuration();
		      c.AddAssembly(Assembly.GetCallingAssembly());
		      factory = c.BuildSessionFactory();
		    }
	   	    catch (Exception ex)
	   	    {
	   	    	 MessageBox.Show(" Erro : " + ex.Message.ToString());
	   	    	 Application.Exit();
	   	     }
              }
	   return factory.OpenSession();				      
} | 
O código deste método carrega as
informações dos arquivos hbml.xml definidos no projeto:
Configuration
c = new Configuration();
c.AddAssembly(Assembly.GetCallingAssembly());
e do arquivo App.Config da aplicação:
factory
= c.BuildSessionFactory();
criando uma sessão que será retornada e usada em nossa
aplicação:
return
factory.OpenSession(); 
Todas as operações que iremos
realizar vão usar esta sessão que foi criada.
Para começar vou mostrar como acessar os dados dos empregados e exibi-los no formulário no controle ListBox.
Isso é feito quando o usuário clica no botão Exibir Empregados. O código associado ao evento Click deste botão é o seguinte:
| //exibe os empregados
void BtnExibirClick(object sender, EventArgs e)
{
	using (ISession session = OpenSession())
	{
		try{
			IQuery query = session.CreateQuery("from Empregado as emp order by emp.nome asc");
			IList<Empregado> procuraEmpregados = query.List<Empregado>();
			lstEmpregados.Items.Clear();
			lstEmpregados.Items.Add("Empregado(s) encontrado(s) : " + procuraEmpregados.Count);
		
			foreach( Empregado empregado in procuraEmpregados )
				lstEmpregados.Items.Add(empregado.empregadoID());
		        }
	catch (Exception ex)
	{
	      MessageBox.Show(" Erro : " + ex.Message.ToString());
	 }
     }			
}		 | 
Neste código estamos usando a linguagem de consulta do NHibernate chamada HQL- Hibernate Query Language. Ela é parecida com a SQL mas é orientada a objetos e possui recursos de herança, polimorfismo e associação.
Nota: para mais detalhes sobre a HQL consulte o site oficial do NHibernate: https://www.hibernate.org/hib_docs/nhibernate/html/queryhql.html
Primeiro obtemos a sessão que foi criada e definimos a consulta para obter os empregados da entidade Empregado que foi mapeada do banco de dados.
IQuery query = session.CreateQuery("from Empregado as emp order by emp.nome asc");
Em seguida obtemos uma coleção dos objetos Empregado:
IList<Empregado> procuraEmpregados = query.List<Empregado>();
Exibimos o total de empregados encontrados:
lstEmpregados.Items.Add("Empregado(s) encontrado(s) : " + procuraEmpregados.Count);
Percorremos a coleção e exibimos o ID e o nome do empregado no ListBox:
foreach(
Empregado empregado in procuraEmpregados )
        lstEmpregados.Items.Add(empregado.empregadoID());
O resultado da execução exibe a seguinte janela:
|  | 
Vejamos agora como incluir um novo empregado. Para fazer isso o cliente digite o nome do empregado na caixa de texto Nome e aciona o botão Cria Empregado cujo código é dado a seguir:
| //chama
        a rotina para criar um novo empregado void BtnCriaEmpregadoClick(object sender, EventArgs e) { if (txtNomeEmpregado.Text.Equals("")) { MessageBox.Show("Informe o nome do Empregado."); } else { string nomeEmpregado = txtNomeEmpregado.Text; CriaEmpregadoSalvandoNoBancodeDados(nomeEmpregado); } } | 
Neste código estamos apenas chamando a rotina CriaEmpregadoSalvandoNoBancoDeDados() passando o nome do empregado. A seguir temos o código desta rotina :
| //cria um  novo empregado
static void CriaEmpregadoSalvandoNoBancodeDados(string novoEmpregado)
{
	   Empregado empregado = new Empregado();
               empregado.nome = novoEmpregado ;
	    empregado.gerente = null ;
	
	   using (ISession session = OpenSession())
	   {
	   	  using( ITransaction transaction = session.BeginTransaction())
    	      {
	   		  try
	   		  {
   	             session.Save(empregado);
    			     transaction.Commit();
           	 MessageBox.Show("Salvando o novo empregado  :: " + empregado.nome + " ::  no banco de dados");
	   		  }
	   		  catch (Exception ex)
	   		  {
	   		  	 MessageBox.Show(" Erro : " + ex.Message.ToString());
	   		  }
   	  }
	  }
 } | 
Criamos um novo objeto empregado do tipo Empregado e atribuímos o seu nome e o gerente como null.
Usamos a sessão que foi criada e iniciamos uma transação para em seguida usar o método Save e salvar os dados na base de dados.
Por trás dos panos o NHibernate esta executando o comando SQL:
Insert into Empregado(nome,gerente) values ('James Taylor',null)
Observe que a coluna id não esta sendo inicializada pois esta propriedade é gerada automaticamente pelo banco de dados.
O resultado da execução desta operação e exibida na figura abaixo:
|  | 
Para atualizar as informações de um empregado precisamos informar o nome que desejamos alterar e o novo nome. e clicar no botão Atualizar Empregado que possui o seguinte código:
| //chama a rotina para atualizar o nome do empregado
void btnAtualizaCriaNovoEmpregadoClick(object sender, EventArgs e)
{
	if(txtNomeAnteriorEmpregado.Text.Equals("") || txtNovoNomeEmpregado.Text.Equals(""))
	{
	   	MessageBox.Show("Informe o nome do Empregado e o novo Nome.");
	}
	else
	{
	   string nomeAnteriorEmpregado = txtNomeAnteriorEmpregado.Text;
	   string noveNomeEmpregado     = txtNovoNomeEmpregado.Text;
		   AtualizaEmpregado(nomeAnteriorEmpregado,noveNomeEmpregado);
	}
} | 
Aqui usamos a rotina AtualizaEmpregado() passando o nome anterior e o novo nome. O código desta rotina é dado abaixo:
| //atualiza o nome de um empregado
static void AtualizaEmpregado(string nomeEmpregado, string novoNomeEmpregado)
{
	using (ISession session = OpenSession())
	{
	  using (ITransaction transaction = session.BeginTransaction())
	  {
		try{
			IQuery q = session.CreateQuery("from Empregado where nome = '" + nomeEmpregado + "'");
			Empregado empregado = q.List<Empregado>()[0];
			empregado.nome = novoNomeEmpregado;
			transaction.Commit();
			MessageBox.Show("Empregado  :: " + nomeEmpregado + "  :: foi Atualizado ");
	    }
   	    catch (Exception ex)
   	    {
   	   	    MessageBox.Show(" Erro : " + ex.Message.ToString());
   	    }
       }
     }
} | 
Usamos a sessão que foi criada e iniciamos uma transação.
Criamos uma consulta HQL para o obter o objeto empregado com o nome informado e atualizamos o nome anterior pelo informado e em seguida salvamos as alterações consolidando (Commit) a transação. Abaixo vemos o resultado da operação:
|  | 
Para excluir um empregado o cliente informa o nome e clica no botão Excluir. Esta operação usa a rotina ExcluiEmpregado exibida abaixo:
| //exclui um  novo empregado
static void ExcluiEmpregado(string nomeEmpregado)
{
	using (ISession session = OpenSession())
	{
	  using (ITransaction transaction = session.BeginTransaction())
	  {
		try{
			IQuery q = session.CreateQuery("from Empregado where nome = '" + nomeEmpregado + "'");
			Empregado empregado = q.List<Empregado>()[0];
			session.Delete(empregado);
			transaction.Commit();
			MessageBox.Show("Empregado  :: " + nomeEmpregado + "  :: foi excluido. ");
	    }
   	    catch (Exception ex)
   	    {
   	   	    MessageBox.Show(" Erro : " + ex.Message.ToString());
   	    }
       }
   }			
}		 | 
Usamos a sessão que foi criada e iniciamos uma transação.
Definimos uma consulta HQL para obter o objeto empregado pelo nome informado e usamos o método Delete() para excluir o objeto consolidando(comitando) a transação. Abaixo vemos o resultado da exclusão:
|  | 
Podemos repetir todo o processo acima usando o banco de dados SQL Server que foi criado na primeira parte do artigo. Para isso basta alterar o arquivo de configuração App.Config usando os valores que estão comentados para o driver, a string de conexão e o dialeto e comentando os valores usados para o MySQL. Feito isso basta rodar a aplicação novamente que o acesso será feito no SQL Server. No resto é tudo igualzinho ao que já foi mostrado.
Com isso mostrarmos como realizar as operações básicas de consulta e persistência (CRUD) usando o NHibernate e a linguagem C# e usando dois banco de dados para mostrar a versatilidade do NHibernate.
Pegue o projeto completo aqui: NHibernate_AloMundo.zip
Aguarde em breve outros artigos sobre o NHibernate.
Eu sei é apenas NHibernate, mas eu
gosto...
| 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 ? | 
Referências:
VB .NET - Usando o NHibernate - Apresenta a utilização do NHibernate com o VB .NET;
NHibernate -Efetuando o mapeamento XML - Mostra exemplos de mapeamentos;
.NET - NHibernate a revanche - Gerando os arquivos de mapeamento com o MyGeneration;
NHibernate - Usando o ActiveRecord I - Ganhando produtividade com o NHibernate (3 artigos);
José Carlos Macoratti