Archive for the ‘NHibernate’ Category

NHibernate para iniciantes

12/07/2012

Esse é o primeiro post de uma possível série sobre o NHibernate.

NHibernate para quem não sabe é uma poderosa ferramenta para ORM. Portado para o .net a partir do Hibernate Core originalmente escrito em Java como diz o site oficial do projeto.

Para iniciar vou criar um pequeno projeto de exemplo, onde terei uma entidade representando meus clientes como visto abaixo:

E a classe Cliente:

namespace Dominio
{
public class Cliente
{
public virtual int ID { get; set; }
public virtual string Nome { get; set; }
public virtual long CPF { get; set; }
public virtual string Email { get; set; }
}
}

Notem que todas as propriedades tem o modificador virtual, isso é por conta do lazy-load ser o modelo default do NHibernate, mas voltaremos nesse ponto mais tarde.
Também precisaremos de uma tabela em um banco de dados para a persistência dos dados:

Agora vamos ao NHibernate, o primeiro passo é adicionar as referencias que ele utiliza. Para isso utilizarei o Nuget no VS2010:

Observação: Instalei apenas o NHibernate, o Iesi.Collections é instalado automaticamente.
Agora vamos ao mapeamento da entidade… Mas o que é um mapeamento?
Simples, é o que usamos para dizer ao sistema em que tabela está sua entidade e quais campos representam cada propriedade. (Pelo menos de forma superficial é isso!)
Por padrão NHibernate utiliza arquivos xml para descrever esse mapeamento. Veremos outras formas mais adiante…

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Dominio" namespace="Dominio">
<class name="Cliente">
<id name="ID">
<generator class="sequence"/>
</id>
<property name="Nome"/>
<property name="CPF"/>
<property name="Email"/>
</class>
</hibernate-mapping>

Notem que em momento nenhum definimos nomes de tabela ou de campos, então o NHibernate assume que os nomes são idênticos. Caso queira nomes distintos existem os atributos table e column nas tags class e property/id respectivamente.
Outra informação interessante é a tag generator que define o tipo do incremento na tabela.

UPDATE: Esse arquivo deve ter a propriedade Build Action marcado como Embedded-Resource na aba propriedades

E agora precisamos configurar o NHibernate para acessar o banco de dados.
Como? Com outro arquivo xml!

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
<session-factory>
<property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
<property name="dialect">NHibernate.Dialect.MsSql2008Dialect</property>
<property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
<property name="connection.connection_string">Data Source=.\SQLEXPRESS;Initial Catalog=FunilariaKaiser;Integrated Security=True</property>
<property name="show_sql">true</property>
</session-factory>
</hibernate-configuration>

Esse xml define qual o banco de dados e o tipo de conexão. Existe uma ampla gama de providers disponíveis.

UPDATE: Esse arquivo deve ter a propriedade Copy to Output Directory marcado como Copy always na aba propriedades

Por fim o nosso domínio está preparado para NHibernate. Mas como manipulamos os dados? Bem para isso vou utilizar um repositorio descrito por Eric Evans no livro DDD.
Para isso criei uma nova classe chamada RepositorioClientes:

using NHibernate;
using NHibernate.Cfg;

namespace Dominio
{
public class RepositorioClientes
{
private ISessionFactory _sessionFactory;

public RepositorioClientes()
{
var configuration = new Configuration();
configuration.Configure();
configuration.AddAssembly(typeof(Cliente).Assembly);
_sessionFactory = configuration.BuildSessionFactory();
}

public void Salvar(Cliente cliente)
{
using (ISession session = _sessionFactory.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
session.Save(cliente);
transaction.Commit();
}
}
}
}
}

Notem que no construtor dessa classe crio uma instancia de Configuration, esse é o responsável por interpretar os xml’s que criamos anteriormente.
No método Salvar, solicito uma sessão ao NHibernate na chamada de OpenSession onde poderei persistir meus objetos sem me preocupar com a estrutura ou linguagem do banco de dados.
Vamos a um exemplo:

using System;
using Dominio;

namespace ConsoleFunilaria
{
class Program
{
static void Main(string[] args)
{
var repositorioClientes = new RepositorioClientes();
var cliente = new Cliente
{
Nome = "Bruno Costa",
CPF = 98765432100,
Email = "brunocosta@refatorando.wordpress.com"
};

repositorioClientes.Salvar(cliente);
Console.WriteLine("\n\nCódigo do cliente: {0}", cliente.ID);
}
}
}


Por hora era isso pessoal, espero que tenha sido claro!
Se alguém estiver afim comente, isso vai ajudar os próximos posts ficarem melhores.
Até a próxima!

Anúncios