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