SlideShare uma empresa Scribd logo
1 de 66
Baixar para ler offline
Programação OO com NHibernate




      Humberto Cardoso Marchezi


                2010
Programação OO com NHibernate

    Agenda

    Dia 1: Fundamentos de NHibernate

    Para que serve ?

    Quais as vantagens ?

    O que é mapeamento objeto-relacional ?

    Como funciona o mapeamento objeto-relacional no NHibernate ?

    Exercícios (Mapeando uma classe simples – apenas
    propriedades)
Programação OO com NHibernate

    Agenda

    Dia 2: Associações no NHibernate

    Como implementar uma associação vários-para-um (simples) ?

    Exercício

    Como implementar uma associação vários-para-um (posse) ?

    Exercício

    Como implementar uma associação um-para-vários ?

    Exercício
Programação OO com NHibernate

    Agenda

    Dia 3: Associações no Nhibernate e Herança

    Como implementar uma associação vários-para-vários ?

    Exercício

    Herança

    Uma Tabela para cada Classe

    Exercício

    Uma Tabela para Toda a Herança

    Exercício
Programação OO com NHibernate

    Agenda

    Dia 4: Objetos de Valor

    Objetos de Valor e Entidades

    Como implementar um objetos de valor

    Exercício
Fundamentos de NH
    
          Para que serve ?
    
          Automatizar a relação entre dois mundos:
    
          As tabelas/visões do banco relacional ( dados )
    
          As classes do mundo dos objetos ( domínio do problema )


Modelo de Objetos                                              Modelo de Dados

 class PessoaFisica                                             table PessoaFisica
                      session
                                                      select
 class Documento       .SaveUpdate(p);                           table Documento
                                                      insert
                                         NHibernate
                                                      update
  class Endereco      session                                    table Endereco
                                                      remove
                       .Remove(p);
       class                                                          table
  TipoDocumento                                                  TipoDocumento
Fundamentos de NH
     
            Para que serve ?
     
            Geração Automática de Comandos SQL
TipoDocumento tp = new TipoDocumento();         insert into Geral_TipoDocumento
tp.Descricao = “Tipo Doc Qualquer”;             ( descricao ) values
                                                ( “Tipo Doc Qualquer” )
session.SaveOrUpdate(tp);
                                                select
TipoDocumento tp = session                      tp.codTipoDocumento, tp.descricao
                     .Get<TipoDocumento>(12);   from Geral_TipoDocumento tp
                                                where tp.codTipoDocumento = 12
tp.Descricao = “Outro Tipo Doc”;
                                                update Geral_TipoDocumento tp
                                                set
session.SaveOrUpdate(tp);                       tp.descricao = “Outro Tipo Doc”
                                                where tp.codTipoDocumento = 12

session.Delete(tp);                             delete Geral_TipoDocumento
                                                where tp.codTipoDocumento = 12
Fundamentos de NH
                                      Ao invés disso (Programação comum)
                                      if (nome == string.Empty)
 
       Vantagens                      {
                                          throw new Exception(“nome vazio”);
 
       POO – Abstrair                 }
                                      if (numCPF == null)
       complexidade das               {
                                       throw new Exception(“cpf não foi informado”);
       regras de negócio              }
                                      ......... Lógica para validar o CPF..........
       (Escrever código que           if (numCEP == null)
       parece fácil)                  {
                                        throw new Exception(“CEP não informado”);
                                      }
Isso (Programação OO)
                                      ............. Lógica para validar o CEP ...............
PessoaFisica p=new PessoaFisica(      ............. Lógica para trazer endereco pelo CEP..
       nome,                          string sql = “insert into Pessoa (nome, cpf,
       new DocumentoCPF(numCPF),      numero, cep, codLogradouro, codBairro,
       new Endereco(numCEP,           codLocalidade, codEstado, codPais) values
                     numEndereco));   (“nome + ”,” + cpf + ”,” + numero + ”,” + cep + ”,” +
                                      codLogr.................................
session.Save(p);                      SqlCommand sql = new SqlCommand(sql);
                                      .......... Continua e nem cabe aqui o código .......
Fundamentos de NH
   
         Vantagens
   
         Essa relação não precisa ser 1 classe = 1
         tabela havendo um espaço para flexibilidade
         entre os dois modelos
Modelo de Objetos              Modelo de Dados

        Pessoa                              TabPesso
                                               a
  Pessoa     Pessoa                       TabDocument
                                               o
       Document         Taxa
          o                               TabDocument
             ValorFinanceiro                   o
Fundamentos de NH

    Vantagens

    Permite que o DBA se concentre na melhor
    forma de modelar os dados e os
    Analistas/Programadores se concentrem na
    melhor forma de representar as entidades e
    regras do problema a ser modelado
Fundamentos de NH
       
              Vantagens
       
            Classes podem ser escritas em C# puro sem
            qualquer tipo de implementação específica
            como herdar de classe específica ou
public classinterface
             ImpostoX     public class ImpostoX public class ImpostoX
{                         {                     {
    protected decimal _valor;            protected decimal _valor;       protected decimal _valor;
    protected ImpostoX() { }             public ImpostoX() { }           public ImpostoX() { }
    public ImpostoX(decimal valor)       public decimal Valor {          public void AtribuirValor
    {                                      get { return _valor; }          (decimal valor)
      _valor = valor;                      set { _valor = value; }       {
    }                                    }                                 _valor = valor;
    public decimal Valor             }                                   }
    {                                                                    public decimal ObterValor( )
      get { return _valor; }                                             {
    }                                                                      return _valor;
}                                                                        }
                                                                     }
Fundamentos de NH

    Vantagens

    Reuso de código ao invés de copy/paste

    Garantia de qualidade: testes unitários

    Legibilidade, manutenibilidade, extensibilidade, etc.
Fundamentos de NH

    O que é mapeamento objeto-relacional ?

    Técnica que consiste em traduzir (criar um tipo
    “de .... - para ... “) entre as classes e suas
    propriedades no modelo-de-objetos e as
    tabelas/visões e suas colunas no modelo de dados

    No NHibernate esse mapeamento é feito através de
    arquivos no padrão XML ( *.hbm.xml )

    A partir desses arquivos, o NHibernate sabe como
    gerar os SQLs automatizados para as classes
Fundamentos de NH

        O que é mapeamento objeto-relacional ?
public class TipoHistorico
{

    protected TipoHistorico( ) { }
    public TipoHistorico
             (string descricao) {    tabela Geral_TipoHistorico
      _descricao = descricao;
    }                                codTipoHistorico int PK
    protected long _id;
    public long Id {                 descricao varchar(50)
      get { return _id; }
      set { _id = value; }
    }
    protected string _descricao;
    public string Descricao {
      get { return _descricao; }
      set { _descricao = value; }
}
Fundamentos de NHibernate

    Como funciona o mapeamento objeto-relacional no
    NHibernate ?
                             TipoDocumento.cs
        using System;

        namespace ControleCorporativo.ControleGeral.DP
        {
             public class TipoDocumento
             {
                     private long _id;
                     public long Id
                     { get { return _id; } set { _id = value; } }

                        private string _descricao;
                        public string Descricao
                        { get { return _descricao; } set { _descricao =
        value; } }
                }
        }
Fundamentos de NHibernate

    Como funciona o mapeamento objeto-relacional no
    NHibernate ?
                   Tabela Geral_TipoDocumento
              create table Geral_TipoDocumento
              (
                     codTipoDocumento INT primary key,
                     descricao varchar(60)
              )
Fundamentos de NHibernate
  
        Como funciona o mapeamento objeto-relacional no
        NHibernate ?
                                TipoDocumento.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">
       <class name="ControleCorporativo.ControleGeral.DP.TipoDocumento"
            table="Geral_TipoDocumento">

                <id name="Id" column="codTipoDocumento">
                       <generator class="identity"/>
                </id>

                <property name="Descricao" column="descricao" access="field.camelcase-
underscore"/>

       </class>
</hibernate-mapping>
Fundamentos de NHibernate

       Como funciona o mapeamento objeto-relacional no
       NHibernate ?

       Configuração: ( necessárioconfiguração para o NHibernate
             Criando uma classe de na primeira vez )
    using System;
    using NHibernate.Cfg;

    namespace SistemaX.Persistencia
    {
      public class ConfiguracaoNH
      {
         public static Configuration CriarConfiguracao()
         {
           Configuration config = new Configuration();
           config.Properties["query.substitutions"] = "true 1,false 0";
           config.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider";
           config.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect";
           config.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver";
    config.Properties["connection.connection_string"] =
                               "server=ColibriSQL2005;database=bdcurso;user id=usr_aluno;"+
                               "password=aluno;connect timeout=60";
           config.AddAssembly("SistemaX.Dominio");
           return config;
         }
      }
    }
Fundamentos de NHibernate

    Como funciona o mapeamento objeto-relacional no
    NHibernate ?

    Criando um singleton para a ISessionFactory vez )
    Configuração: ( necessário na primeira (NHibernateHelper.cs)
    using NHibernate;

    namespace SistemaX.Persistencia
    {
      public class NHibernateHelper
      {
        // A ISessionFactory é unica para toda a aplicação e
        // é responsável por processar todos os mapeamentos
        // do NHibernate
        private static readonly ISessionFactory sessionFactory =
                 ConfiguracaoNH.CriarConfiguracao().BuildSessionFactory();

            public static ISessionFactory ObterSessaoFactory()
            {
              return sessionFactory;
            }
        }
    }
Fundamentos de NHibernate

     Como funciona o mapeamento objeto-relacional no
     NHibernate ?
                                    Inserindo
// Abre a sessao com o banco
ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession();

// Cria um tipo de documento
TipoDocumento tp = new TipoDocumento() { Descricao = “Novo Tipo Documento” };

// Inicia Transação
ITransaction tx = sessao.BeginTransaction();

// Salva o tipo de documento
sessao.Save(tp);

// Confirma Transação
tx.Commit();

// Fecha a sessão com o banco
sessao.Close();
Fundamentos de NHibernate

     Como funciona o mapeamento objeto-relacional no
     NHibernate ?
                                    Alterando
    // Abre a sessao com o banco
    ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession();

    // Cria um tipo de documento
    TipoDocumento tp = sessao.Get<TipoDocumento>(10);

    // Inicia Transação
    ITransaction tx = sessao.BeginTransaction();

    // Salva o tipo de documento
    sessao.Update(tp);

    // Confirma Transação
    tx.Commit();

    // Fecha a sessão com o banco
    sessao.Close();
Fundamentos de NHibernate

      Como funciona o mapeamento objeto-relacional no
      NHibernate ?
                                    Removendo

    // Abre uma sessão com o banco
    ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession();

    // Inicia uma transação
    ITransaction transacao = session.BeginTransaction();

    // Recupera um tipo de documento com chave = 10
    TipoDocumento tipoDocumento = session.Get<TipoDocumento>(10);

    // Deletando um tipo de documento
    session.Delete(tipoDocumento);

    // Confirma a transação
    transacao.Commit();

    // Fecha a sessão com o banco
    session.Close();
Fundamentos de NHibernate

      Como funciona o mapeamento objeto-relacional no
      NHibernate ?
                              Consultando (com HQL)
    // Abre uma sessão com o banco
    ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession();

    // Executa uma consulta em HQL, resultado como lista de objetos
    string strHQL = “from TipoDocumento tp where tp.Descricao like '%CP%'”;
    IList<TipoDocumento> lstResultado = session.CreateQuery(strHQL)

    .List<TipoDocumento>();

    string strMensagem = string.Empty;
    foreach(TipoDocumento tp in lstResultado)
    {
            strMensagem += “ Id = “ + tp.Id + “ Desc = “ + tp.Descricao + “n”;
    }

    MessageBox.Show(strMensagem);

    // Fecha a sessão com o banco
Fundamentos de NHibernate

        Como funciona o mapeamento objeto-relacional no
        NHibernate ?
                                Consultando (com HQL)
    // Abre uma sessão com o banco
    ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession();

    // Executa uma consulta em HQL, resultado como lista de objetos
    IList<TipoDocumento> lstResultado = (from tp in session.Linq<TipoDocumento>()
                                                               where
    tp.Descricao.Contains(“CP”)
                                                               select tp).ToList();

    string strMensagem = string.Empty;
    foreach(TipoDocumento tp in lstResultado)
    {
            strMensagem += “ Id = “ + tp.Id + “ Desc = “ + tp.Descricao + “n”;
    }

    MessageBox.Show(strMensagem);

    // Fecha a sessão com o banco
Fundamentos de NHibernate
     
             Como funciona o mapeamento objeto-relacional no
             NHibernate ?
Template de mapeamento
<?xml version ="1.0" encoding ="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2 " assembly="[DLL onde está a classe] "
 namespace="[namespace da classe (using)] ">

 <class name="[nome da classe] " table="[nome da tabela] " lazy="true">

  <id name="[propriedade de id] " column="[chave primária] " type="[nome do tipo na classe] ">
   <generator class="[ native | identity | sequence | assigned | outros ] "/>
  </id>

<property name="[campo1 da classe] " type="[tipo na classe] " column="[coluna1 na tabela] "
accessor ="field.camelcase-underscore " />
<property name="[campo2 da classe] " type="[tipo na classe] " column="[coluna2 na tabela] "
accessor ="field.camelcase-underscore " />
<property name="[campo3 da classe] " type="[tipo na classe] " column="[coluna3 na tabela] "
accessor ="field.camelcase-underscore " />
       :       :        :              :      :     :         :     :         :         :        :   :
 <property name="[campoN da classe] " type="[tipo na classe] " column="[colunaN na
tabela]"accessor ="field.camelcase-underscore " />

</class>

</hibernate-mapping >
Fundamentos de NHibernate
 
      Exercício
 
       Dada a classe Pessoa ( em pseudo código ) e a tabela Pessoa abaixo, criar uma mini-
      aplicação web de cadastro utilizando NHibernate.
 
      class Orgao { public long Id {get;set;}; public string Descricao
      {get;set;}; }
 
      create table Orgao (codOrgao INT primary key, descricao varchar(50) NOT
      NULL )

 
      Campos Incluir
      txtDesc da mini aplicação web:
         r
      Nome:
 
       txtId    Remov
          Id:
                  er
 
        txtId        txtDesc         Alterar
                         r
txtDesc Pesquisa
 
          Id:        Nome:
    r         r


                ListBox
Associações no NHibernate

    DIA 2
Associações no NHibernate
     
            Convenção para notação de classes em C#.NET
         TipoDocumento.cs (Completo)                    TipoDocumento.cs (Simplificado)
using System;                                           public class TipoDocumento
namespace ControleCorporativo.ControleGeral.DP          {
{                                                               public long Id { get; set; }
       public class TipoDocumento                               public string Descricao {get;
       {                                                set; }
               private long _id;                        }
               public virtual long Id
               {
                       get { return _id; }
                       protected set { _id = value; }
               }
               private string _descricao;
               public string Descricao
               {
                       get { return _descricao; }
                       set { _descricao = value; }
               }
       }
Associações no NHibernate
  
          Como implementar mapeamento sem
          associacões ?
               C#.NET                   SQL
public class Orgao                                   create table Orgao
{                                                    (
 public long Id { get; set; }                          codOrgao INT primary key,
 public string Descricao {get; set;}                   descricao varchar(50)
}                                                    )
                                      Orgao.hbm.xml
   <?xml version="1.0" ?>
   <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">
    <class name="SistemaX.Dominio.Orgao" table="Orgao">

       <id name="Id" column="codOrgao">
        <generator class="identity"/>
       </id>

       <property name="Descricao" column="descricao" access="field.camelcase-underscore"/>

      </class>

   </hibernate-mapping>
Associações no NHibernate
     
          Associação vários-para-um (Associação)

                C#.NET                                  SQL
public class Pessoa                      create table Pessoa
{                                        (
      public long Id { get; set; }            codPessoa INT primary key,
      public string Nome { get; set; }        nome varchar(50),
      public Orgao Lotacao { get; set; }      codOrgao INT
}                                        )

public class Orgao                          create table Orgao
{                                           (
      public long Id { get; set; }               codOrgao INT primary key,
      public string Descricao { get; set; }      descricao varchar(50)
}                                           )
Associações no NHibernate
      
             Associação vários-para-um (Associação)
                                           Pessoa.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[assembly]">
        <class name="SistemaX.Dominio.Pessoa" table="Pessoa">

               <id name="Id" column="codPessoa">
                      <generator class="identity" />
               </id>

               <property name="Nome" column="nome" access="field.camelcase-underscore"/>

<many-to-one name=”Lotacao” class="Orgao" column=”codOrgao” access="field.camelcase-underscore"/>

        </class>
</hibernate-mapping>
Associações no NHibernate
  
        Associação vários-para-um (Associação)
Exemplo de código C# para alteração do Orgão onde uma Pessoa esta lotada:

ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession();
ITransaction trans = sessao.BeginTransaction();

// Obtem um orgao do banco-de-dados
Orgao orgao = sessao.Get<Orgao>((long)45);

// Cria uma nova pessoa
Pessoa p = sessao.Get<Pessoa>((long)70);

p.Lotacao = orgao;
 // Salva a pessoa
sessao.Save(p);

trans.Commit();
sessao.Close();
Associações no NHibernate

    Exercício (vários-para-um) (associação)

    Incluir Pessoa

    Nome txtNome                   Incluir
                     Orgao cmbbxOrgao

    Alterar Pessoa

    Pelo Id txtIdPessoa   Nome txtNome                 Alterar
                                         Orgao cmbbxOrgao

    Remover Pessoa
                   Remove
    Pelo Id txtIdPessoa
                        r
Associações no NHibernate
    
          Associação vários-para-um (composição)
                  C#.NET                                     SQL

public class Pessoa                            create table Pessoa
{                                              (
      public long Id { get; set; }                   codPessoa INT primary key,
      public string Nome { get; set; }               nome varchar(50),
      private Endereco _endereco =                   codEndereco INT
            new Endereco();                    )
      public Endereco Endereco { get; }
}                                              create table Endereco
                                               (
public class Endereco                                codEndereco INT primary
{                                              key,
      public long Id { get; set; }                   localidade varchar(50)
      public string Localidade { get; set; }   )
}
Associações no NHibernate

        Associação vários-para-um (Posse)
                                Pessoa.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[assembly]">
        <class name="SistemaX.Dominio.Pessoa" table="Pessoa">
                 ..................... outros mapeamentos ..........................
<many-to-one name=”Endereco” class="Endereco" column=”codEndereco”
               access="field.camelcase-underscore" cascade="all"/>
        </class>
</hibernate-mapping>
                                   Endereco.hbm.xml
    <?xml version="1.0" encoding="utf-8" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">

     <class name="SistemaX.Dominio.Endereco" table="Endereco">

      <id name="Id" column="codEndereco">
       <generator class="identity"/>
      </id>

      <property name="Localidade" column="localidade" access="field.camelcase-
    underscore"/>

     </class>
Associações no NHibernate
  
        Associação vários-para-um (Posse)
ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession();
ITransaction trans = sessao.BeginTransaction();

Exemplo de código C# para inclusão de Pessoa com Endereco:

 // Cria uma nova pessoa com Endereco
Pessoa p = new Pessoa( )
p.Nome=”Nova Pessoa”;
p.Endereco.Localidade = “Anchieta”;
sessao.Save(p);

Exemplo de código C# de alteração de endereço de uma Pessoa existente no banco:

// Alterando a localidade de uma pessoa grvada em banco
Pessoa p2 = sessao.Get<Pessoa>((long)70);
p2.Endereco.Localidade = “Outra Localidade”;
sessao.Update(p);

trans.Commit();
sessao.Close();
Associações no NHibernate

    Exercício (associação vários-para-um)

    Incluir Pessoa

    Id da Pessoa txtIdPessoa Nome txtNome Localidade txtLocalidade
                                                                 Incluir

    Alterar Pessoa
                                                               Alterar
    Id da Pessoa txtIdPessoa Nome txtNome Localidade txtLocalidade

    Remover Pessoa

                        Remove
    Id da Pessoa txtIdPessoa
                            r
Associações no NHibernate
    
         Associação um-para-vários
                 C#.NET
                                                    SQL
public class Pessoa
                                       create table Pessoa
{                                      (
  public long Id { get; set; }           codPessoa INT primary key,
  public string Nome { get; set; }       nome varchar(50)
  private IList<Documento>             )
_documentos
    = new List<Documento>();           create table Pessoa_Documento
  public IList<Documento> Documentos   (
  { get; }                               codDocumento INT primary key,
}                                        numero varchar(50),
                                         codPessoa int
                                       )
public class Documento
{
  public long Id { get; set; }
  public string Numero { get; set; }
  public Pessoa Pessoa { get; }
Associações no NHibernate
      
             Associação um-para-vários
                                          Pessoa.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">
 <class name="SistemaX.Dominio.Pessoa" table="Pessoa">
       :       :       : outros mapeamentos : :     :      :       :
  <bag name="Documentos" access="field.camelcase-underscore"
        cascade="all-delete-orphan" inverse="true">
    <key column="codPessoa"/>
    <one-to-many class="SistemaX.Dominio.Documento"/>
  </bag>

 </class>
</hibernate-mapping>

                                         Documento.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[DLL]" namespace="[namespace]">
        <class name="DocumentoPessoa" table="Pessoa_DocumentoPessoa" lazy="true">
                 <id name="Id" column="codDocumentoPessoa" type="Int64">
                         <generator class="identity" />
                 </id>
                 <property name="numero" column="numero" type="string" access="field.camelcase-underscore"/>
<many-to-one name="relPessoa" class="Pessoa" column="codPessoa" access="field.ca..." not-null="true"/>
        </class>
Associações no NHibernate
  
        Associação um-para-vários
Exemplo de código C# para inclusão de Documento em Pessoa Existente no Banco

ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession();
ITransaction trans = sessao.BeginTransaction();
 // Obtem uma pessoa do banco-de-dados
Pessoa p = sessao.Get<Pessoa>((long)44);
 // Adiciona um documento na Pessoa
Documento d = new Documento() { Numero = “00009900” , Pessoa = p };
p.Documentos.Add(d);
// Altera o primeiro documento da Pessoa
p.Documentos[0].Numero = “000900”;
// Remove o terceiro documento da Pessoa
p.Documentos.Remove( p.Documentos[2] );

 // Salva a pessoa e todas alterações nos documentos de uma só vez
sessao.Update(p);

trans.Commit();
sessao.Close();
Associações no NHibernate

    Exercício (associação um-para-vários)

    Incluir Documento

    Id da Pessoa txtIdPessoa   Desc. Doc. txtDescrDocumento
                                                       Incluir

    Alterar Documento
                                                                       Alterar
    Id da Pessoa txtIdPessoa Id do Doc. txtIdDoc Desc.doc. txtDescrDocumento


    Remover Documento
                                            Remove
                                              r
    Id da Pessoa txtIdPessoa Id do Doc. txtIdDoc
Associações no NHibernate

    Dia4
Associações no NHibernate
   
         Associação vários-para-vários
                     C#.NET                              SQL
public class Pessoa                         create table Pessoa
{                                           (
 public long Id { get; set; }                 codPessoa INT primary key,
 public string Nome { get; set; }             nome varchar(50)
}                                           )

                                            create table PessoaTarefa
                                            (
                                              codPessoa INT,
                                              codTarefa INT
                                            )

public class Tarefa                         create table Tarefa
{                                           (
 public long Id { get; set; }                codDocumento INT primary key,
 public string Descricao {get; set;}         descricao varchar(50),
 public IList<Pessoa> Pessoas {get; set;}    codPessoa INT
}                                           )
Associações no NHibernate
  
            Associação vários-para-vários

                                      Tarefa.hbm.xml
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">

 <class name="SistemaX.Dominio.Tarefa" table="Tarefa" lazy="true">

  <id name="Id" column="codTarefa">
   <generator class="identity"/>
  </id>

  <property name="Descricao" column="descricao" access="field.camelcase-underscore"/>

  <bag name="Pessoas" table="Pessoa_Tarefa" access="field.camelcase-underscore"
       lazy="true" inverse = "false" cascade="all">
    <key column="codTarefa"/>
    <many-to-many class="SistemaX.Dominio.Pessoa" column="codPessoa"/>
  </bag>

 </class>

</hibernate-mapping>
Associações no NHibernate

    Exercício (associação Vários-para-vários)

    Incluir Tarefa
                Incluir
    Nome txtDescricao

    Alterar Tarefa
                                          Alterar
    Pelo Id txtIdTarefa Descricao txtDescricao

    Remover Tarefa

                    Remove
    Pelo Id txtIdTarefa
                        r

    Incluir Pessoa na Tarefa

    Tarefa   txtIdTarefa                  Incluir
                           Pessoa txtIdPessoa

    Remover Pessoa da Tarefa

    Tarefa txtIdTarefa                   Remove
                           Pessoa txtIdPessoa
                                            r
Associações no NHibernate
    
            Template de mapeamento: (Resumo)
Template de classe
using System;
namespace AlgumNamespace
{
    public class AlgumaClasse
    {
         private long _id;
         public virtual long Id { get { return this._id; } protected set { this._id = value; } }

            protected tipo _campo;
            public virtual tipo Campo
              { get { return this._campo; } set { this._campo = value; } }

            protected OutraClasse _associacao;
            public virtual OutraClasse Associacao
              { get { return this._associacao; } set { this._associacao = value; } }

            protected IList<MaisOutraClasse> _associacaoLista;
            public virtual IList<MaisOutraClasse> AssociacaoLista
              { get { return this._associacaoLista; } set { this._associacaoLista = value; } }
        }
}
Associações no NHibernate
       
               Template de mapeamento: (Resumo)
Template de mapeamento
<?xml version ="1.0" encoding ="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2 " assembly="[DLL da classe] " namespace ="[namespace] ">
 <class name="[nome da classe] " table="[nome da tabela] " lazy="true">

  <id name="[propriedade de id] " column="[chave primária] " type="[tipo na classe] ">
   <generator class="[ native | identity | sequence | assigned | outros ] "/>
  </id>

 <property name="[campo da classe] " type="[tipo do campo] " column="[coluna na tabela] " accessor ="field.camelcase-
underscore " />

 <many-to-one name="[assoc. da classe] " class="[tipo da assoc.] " column="[chaveFK] "
  cascade ="[none | all | save-update] " access ="field.camelcase-underscore" />

 <bag name="[lista na classe] " lazy="true" cascade ="[ all-delete-orphan | save-update | none ] "
      inverse="true" access ="field.camelcase-underscore">
     <key column="[chave FK na tabela filho] "/>
     <one-to-many class="[tipo de cada elemento na lista1] "/>
 </bag>

 <bag name="[lista da classe] " table="[tabela agregada da associac.] " lazy="true" access="field.camelcase-underscore"
      cascade ="[ all-delete-orphan | save-update | none ] ">
     <key column="[chave FK para a tabela filho] "/>
     <many-to-many class="[tipo de cada elemento na listaN+1] " column="[chave FK para a tabela pai] "/>
 </bag>

</class>
</hibernate-mapping >
Herança

 Estrutura em árvore composta por uma classe pai
(genérica) e as classes filhas (específicas)

 Herança de classe pode ter várias formas no Modelo de
Dados
Uma tabela para toda a hierarquia de classes




Uma tabela por classe




Uma tabela cada cada classe concreta

Herança
 
       Uma tabela para toda a hierarquia
 
       Modelo de Classe                         Modelo de Dados
public abstract class Pessoa                 create table Pessoa
{                                            (
  public long Id { get; set; }                  codPessoa INT primary key,
  public string Nome { get; set; }              nome varchar(50),
}                                               sexo char,
                                                objetoSocial varchar(50),
public class PessoaFisica : Pessoa              tipoPessoa char
{                                            )
  public char Sexo { get; set; }
}

public class Pessoa Juridica : Pessoa
{
  public string ObjetoSocial { get; set; }
}
Herança
    
           Uma tabela para toda a hierarquia
 Pessoa.hbm.xml
 <?xml version="1.0" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio">
         <class name="SistemaX.Dominio.Pessoa" table="Pessoa" lazy="true">
                  <id name="Id" column="codPessoa" type="Int64">
                          <generator class="identity" />
                  </id>
                  <discriminator column=”tipoPessoa” type=”char”/>
                  <property name="Nome" column="nome" type="string" access="field.camelcase-underscore"/>
         </class>
 </hibernate-mapping>

PessoaJuridica.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio">
         <subclass name=”PessoaJuridica” discriminator-value=”j” extends="Pessoa">
                 <property name=”CNPJ” column=”cnpj” access="field.camelcase-underscore"/>
         </subclass>
</hibernate-mapping>


PessoaFisica.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio">
         <subclass name=”PessoaFisica” discriminator-value=”f” extends="Pessoa">
                 <property name=”CPF” column=”cpf” access="field.camelcase-underscore"/>
         </subclass>
</hibernate-mapping>
Herança
 
      Uma tabela por classe
 
      Modelo de Classe                     Modelo de Dados
public abstract class Pessoa            create table Pessoa
{                                       (
  public long Id { get; set; }             codPessoa INT primary key,
  public string Nome { get; set; }         nome varchar(50),
}                                       )

public class PessoaFisica : Pessoa      create table PessoaFisica
{                                       (
  public char Sexo { get; set; }           codPessoa INT primary key,
}                                          sexo char(50),
                                        )
public class Pessoa Juridica : Pessoa
{                                       create table PessoaJuridica
  public string ObjetoSocial { get;     (
set; }                                     codPessoa INT primary key,
}                                          objetoSocial varchar(50),
                                        )
Herança
  
          Uma tabela por classe
       Pessoa.hbm.xml
       <?xml version="1.0" ?>
       <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" >
                <class name="SistemaX.Dominio.Pessoa" table="Pessoa" lazy="true">
                         <id name="Id" column="codPessoa" type="Int64">
                                 <generator class="identity" />
                         </id>
                         <property name="Nome" column="nome" type="string" access="field.camelcase-
       underscore"/>
                </class>
       </hibernate-mapping>
PessoaJuridica.hbm.xml
<?xml version="1.0" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"
namespace="SistemaX.Dominio">
         <joined-subclass name=”PessoaJuridica” table=”PessoaJuridica” lazy="true" extends="Pessoa">
                  <key column=”codPessoa”/>
                  <property name=”ObjetoSocial” column=”objetoSocial” access="field.camelcase-underscore"/>
         </joined-subclass>
</hibernate-mapping>
    PessoaFisica.hbm.xml
    <?xml version="1.0" ?>
    <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"
    namespace="SistemaX.Dominio">
             <joined-subclass name=”PessoaFisica” table=”PessoaJuridica” lazy="true" extends="Pessoa">
                      <key column=”codPessoa”/>
                      <property name=”Sexo” column=”sexo” access="field.camelcase-underscore"/>
             </joined-subclass>
    </hibernate-mapping>
Herança
Exercício (Herança -> 1 tabela para a hierarquia )
Escrever um mapeamento NHibernate para a herança de documentos abaixo:
public class Documento
{
        public long Id { get; set; }             create table Documento
        public string Numero { get; set; }       (
}                                                      codDocumento INT primary
public class DocumentoCI : Documento             key,
{                                                      numero varchar(50),
        public string Estado { get; set; }             estado varchar(50),
}                                                      categoria varchar(50),
public class DocumentoCNH : Documento                  tipoDocumento varchar(50)
{
                                                 )
        public string Categoria { get; set; }
}

Fazer uma tela web de consultar objetos via HQL:
       txtHQL               btExecutar


                              listBoxResultado
Herança
        Exercício (Herança ->1 tabela por classe)

public abstract class Pessoa                       create table Pessoa
{                                                  (
                                                           codPessoa INT primary key,
        public long Id { get; set; }                       ...
        ...                                        )
}                                                  create table PessoaFisica
public class PessoaFisica : Pessoa                 (
{                                                          codDocumento INT,
        public string Sexo { get; set; }                   sexo varchar(50)
}                                                  )
public class PessoaJuridica : Pessoa               create table PessoaJuridica
                                                   (
{                                                          codDocumento INT,
        public string ObjetoSocial { get; set; }           objetoSocial varchar(50)
}                                                  )

Utiliar a mesma tela web de consulta para verificar os mapeamentos
        txtHQL               btExecutar


                                listBoxResultado
Objetos de Valor




      Dia4
Objetos de Valor e Entidades
   Entidade:
   Toda classe cujo objeto precisa de um Id para identif.
   Normalmente esta mapeada para 1 ou mais tabelas
   Ex: Pessoa, Logradouro, InscricaoCadastral
   Objeto de Valor:
   Também é classe mas não possui Id de identificação
   Representa um conceito importante do negócio
   É imutável, não pode ser alterado, apenas subtituído
   Ex: Dinheiro (valor + unid. Ref.), Endereco (alguns casos)
Objetos de Valor e Entidades
  
        Exemplo:
  
        Modelo de Dados                   Modelo de Classes

                                     public class Taxa
create table Taxa
                                     {
(
                                             public long Id { get; set; }
  codTaxa INT primary key,
                                             public string Descricao { get; set; }
  descricao varchar(50),
                                             public UnidadeReferencia
  codUnidadeReferencia INT,
                                     UnidadeReferencia
  valorTaxa numeric(12,4)
                                         { get; set; }
)
                                             public decimal ValorTaxa { get; set; }
                                     }
create table UnidadeReferencia
(
                                     public class UnidadeReferencia
  codUnidadeReferencia INT primary
                                     {
key,
                                             public long Id { get; set; }
  descricao varchar(50)
                                             public string Descricao { get; set; }
)
                                     }
Objetos de Valor e Entidades
  
        Exemplo: (Funciona, mas vamos pensar melhor ... )
  
        Modelo de Dados                   Modelo de Classes

                                     public class Taxa
create table Taxa
                                     {
(
                                             public long Id { get; set; }
  codTaxa INT primary key,
                                             public string Descricao { get; set; }
  descricao varchar(50),
                                             public UnidadeReferencia
  codUnidadeReferencia INT,
                                     UnidadeReferencia
  valorTaxa numeric(12,4)
                                         { get; set; }
)
                                             public decimal ValorTaxa { get; set; }
                                     }
create table UnidadeReferencia
(
                                     public class UnidadeReferencia
  codUnidadeReferencia INT primary
                                     {
key,
                                             public long Id { get; set; }
  descricao varchar(50)
                                             public string Descricao { get; set; }
)
                                     }
Objetos de Valor e Entidades
  
        Exemplo: (Vamos pensar melhor ... )
  
        Modelo de Dados              Modelo de Classes
create table Taxa
(
  codTaxa INT primary key,
  descricao varchar(50),
  codUnidadeReferencia INT,           Essas duas colunas aparecem juntas
  valorTaxa numeric(12,4)             em várias tabelas sugerindo um
)                                     conceito importante de valor financeiro.

create table UnidadeReferencia
(
  codUnidadeReferencia INT primary
key,
  descricao varchar(50)
)
Objetos de Valor e Entidades
   
         Exemplo: ( Incluir conceito de negócio )
   
         Modelo de Dados            Modelo de Classes
create table Taxa             public class Taxa
(                             {
  codTaxa INT primary key,             public long Id { get; set; }
  descricao varchar(50),               public string Descricao { get; set; }
  codUnidadeReferencia INT,            public ValorFinanc Valor { get; set; }
  valorTaxa numeric(12,4)     }
)                             public class ValorFinanc
                              {
                                public ValorFinanc (UnidadeReferencia uf, decimal v)
create table                    public UnidadeReferencia { get; }
UnidadeReferencia               public decimal Valor { get; }
(                               public ValorFinanc static Adicionar( ValorFinanc fator1,
  codUnidadeReferencia                      ValorFinanc fator2, UnidadeReferencia result);
  INT primary key,              public ValorFinanc static Subtr( ValorFinanc subtraendo,
  descricao varchar(50)                     ValorFinanc subtrator, UnidadeReferencia result);
)                               public ValorFinanc Conversao(UnidadeReferencia result);
                              }
                              public class UnidadeReferencia
                              {
                                       public long Id { get; set; }
                                       public string Descricao { get; set; }
                              }
Objetos de Valor e Entidades

      Exemplo: ( Incluir conceito de negócio )

      Mapeamento da classe Taxa
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[DLL]"
                   namespace="[namespace]">
       <class name="Taxa" table="Taxa" lazy="true">

             <id name="Id" column="codTaxa" type="Int64">
                    <generator class="identity"/>
             </id>

      <property name=“Descricao" type="String" column="descricao" not-null="true"
                accessor="field.camelcase-underscore" />

      <component name=“Valor” class=“ValorFinanc”>
            <property name=“Valor” type=“String” column=“valorTaxa”/>
            <many-to-one name=“UnidadeReferencia”
class=“UnidadeReferencia”
                             column=“codUnidadeReferencia”/>
      </component>

       </class>
</hibernate-mapping>
Exercício
Mapear a classe PessoaEspecial
class PessoaEspecial                            create table PessoaEspecial
{                                               (
       public long Id { get; set; }                    codPessoaEspecial INT primary
       public long Nome { get; set; }           key,
       public EnderecoEspecial Endereco                nome varchar(50),
       { get; }                                        localidade varchar(50),
}                                                      numero varchar(50)
                                                )
class EnderecoEspecial
{
       public string Localidade { get; set; }
       public string Numero { get; set; }
}


Testar a inclusão e a consulta de uma pessoa
 especial em C#
Observações
   
    Projeto Fluent Nhibernate permite escrever
   mapeamentos em C#
 1. <?xml version="1.0" encoding="utf-8" ?>
 2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
 3. namespace="QuickStart" assembly="QuickStart">
 4.
                                                              1. public class CatMap : ClassMap<Cat>
 5. <class name="Cat" table="Cat">
                                                              2. {
 6. <id name="Id">
                                                              3. public CatMap()
 7.     <generator class="identity" />
                                                              4. {
 8. </id>
                                                              5. Id(x => x.Id);
 9.
                                                              6. Map(x => x.Name)
10. <property name="Name">
                                                              7.    .WithLengthOf(16)
11.     <column name="Name" length="16" not-null="true" />
                                                              8.    .Not.Nullable();
12. </property>
                                                              9. Map(x => x.Sex);
13. <property name="Sex" />
                                                             10. References(x => x.Mate);
14. <many-to-one name="Mate" />
                                                             11. HasMany(x => x.Kittens);
15. <bag name="Kittens">
                                                             12. }
16.     <key column="mother_id"/>
                                                             13. }
17.      <one-to-many class="Cat"/>
18.     </bag>
19. </class>
20. </hibernate-mapping>
Observações

     
      Consultas em Linq-to-NHibernate
ist<TipoDocumento> lstResultado = (from tp in session.Linq<TipoDocumento>()
                                                         where tp.Descricao.Contains(“CP”)
                                                         select tp).ToList();



     
      Recursos geo-espaciais (MsSQLSpatial, PostGIS)
  // Encontra um país localizado em uma coordenada
  Country country = session.CreateCriteria(typeof(Country))
     .Add(SpatialExpression.Contains("Boundaries", new Point(-70.40, -33.24)))
     .UniqueResult() as Country;

  // Encontra as cidades de uma área exceto aquelas localizadas em algumas coords.
  Town[] towns = Town.FindAll(
     SpatialExpression.Filter("Boundaries", new Envelope(-70, -68, -32, -34)),
     Expression.Not(SpatialExpression.Contains("Boundaries", new Point(-70.40, -33.24)))
  );
Observações

   
    Vantagens só aparecem com Programação OO
                 Isso                                       Ao invés disso
Pessoa p = new Pessoa(                   if ((strNome == null)||(strNome == string.Empty))
             strNome,                    { .....Erro ... }
             new DocumentoCPF(strCPF),   if ((strCPF == null)||(strCPF == string.Empty))
             new Endereco(strCEP));      { ... Erro ... }
session.SaveOrUpdate(p);                 if ((strCEP == null)||(strCEP == string.Empty))
                                         { ... Erro ... }
                                         IList<Pessoa> lstPessoas = ... consulta para achar
                                                                             ... outra pessoa com
                                                                             ... mesmo nome e CPF
                                         if (lstPessoas.Count > 0) { ..... Erro ......... }
                                         CEP cep = ... consulta de CEP pelo numero
                                         if (cep == null ) { ........ Erro ....... }
                                         Localidade localidade = cep.Localidade;
                                         Pessoa p = new Pessoa( );
                                         p.Nome = strNome;
                                         p.Documentos.Add(new DocumentoCPF(strCPF));
                                         p.Endereco.Localidade = localidade;
                                         session.SaveOrUpdate(p);
Perguntas

Contacte o autor, se preferir ...
http://www.linkedin.com/in/hcmarchezi
●



http://hcmarchezi.blogspot.com.br/
●

Mais conteúdo relacionado

Mais procurados (19)

Aula03
Aula03Aula03
Aula03
 
Revisão Sobre Programação Orientada a Objetos com Java
Revisão Sobre Programação Orientada a Objetos com Java Revisão Sobre Programação Orientada a Objetos com Java
Revisão Sobre Programação Orientada a Objetos com Java
 
Curso matlab 6 especiais
Curso matlab 6 especiaisCurso matlab 6 especiais
Curso matlab 6 especiais
 
Linguagem C - Estruturas
Linguagem C - EstruturasLinguagem C - Estruturas
Linguagem C - Estruturas
 
Dinamicas
DinamicasDinamicas
Dinamicas
 
Java 07
Java 07Java 07
Java 07
 
Aula10 diagrama colaboracao
Aula10 diagrama colaboracaoAula10 diagrama colaboracao
Aula10 diagrama colaboracao
 
Java 02
Java 02Java 02
Java 02
 
Orientação a Objetos em Python
Orientação a Objetos em PythonOrientação a Objetos em Python
Orientação a Objetos em Python
 
Introdução ao C#
Introdução ao C#Introdução ao C#
Introdução ao C#
 
Series lab
Series labSeries lab
Series lab
 
Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6
 
POO - 16 - Polimorfismo
POO - 16 - PolimorfismoPOO - 16 - Polimorfismo
POO - 16 - Polimorfismo
 
Programando em python classes
Programando em python   classesProgramando em python   classes
Programando em python classes
 
Iteraveis e geradores
Iteraveis e geradoresIteraveis e geradores
Iteraveis e geradores
 
05 poo-ii
05   poo-ii05   poo-ii
05 poo-ii
 
Python: a primeira mordida
Python: a primeira mordidaPython: a primeira mordida
Python: a primeira mordida
 
Programando em python funcoes
Programando em python   funcoesProgramando em python   funcoes
Programando em python funcoes
 
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
9. Operação toString(); Classes, instâncias e objectos; Scanner – Fundamentos...
 

Destaque

Building Anomaly Detections Systems
Building Anomaly Detections SystemsBuilding Anomaly Detections Systems
Building Anomaly Detections SystemsHumberto Marchezi
 
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...Humberto Marchezi
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkHumberto Marchezi
 
Getting Started with Machine Learning
Getting Started with Machine LearningGetting Started with Machine Learning
Getting Started with Machine LearningHumberto Marchezi
 

Destaque (6)

Building Anomaly Detections Systems
Building Anomaly Detections SystemsBuilding Anomaly Detections Systems
Building Anomaly Detections Systems
 
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...
Um Ambiente Grafico para Desenvolvimento de Software de Controle para Robos M...
 
Padroes de desenho
Padroes de desenhoPadroes de desenho
Padroes de desenho
 
C++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing FrameworkC++ Unit Test with Google Testing Framework
C++ Unit Test with Google Testing Framework
 
Getting Started with Machine Learning
Getting Started with Machine LearningGetting Started with Machine Learning
Getting Started with Machine Learning
 
Machine Learning Basics
Machine Learning BasicsMachine Learning Basics
Machine Learning Basics
 

Semelhante a NHibernate

Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...
Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...
Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...Tchelinux
 
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Leinylson Fontinele
 
Estrutura de Dados - Aula de revisão de c na prática
Estrutura de Dados - Aula de revisão de c na práticaEstrutura de Dados - Aula de revisão de c na prática
Estrutura de Dados - Aula de revisão de c na práticaLeinylson Fontinele
 
Lógica de programação pascal
Lógica de programação   pascalLógica de programação   pascal
Lógica de programação pascalJocelma Rios
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao cprofwtelles
 
Introdução a linguagem c karen lowhany
Introdução a linguagem c   karen lowhanyIntrodução a linguagem c   karen lowhany
Introdução a linguagem c karen lowhanyKaren Costa
 
Estrutura de dados
Estrutura de dadosEstrutura de dados
Estrutura de dadosgjpbg
 
Apostila estrutura de dados 2
Apostila estrutura de dados 2Apostila estrutura de dados 2
Apostila estrutura de dados 2Leandro Lopes
 
Mini-Curso de MongoDB
Mini-Curso de MongoDBMini-Curso de MongoDB
Mini-Curso de MongoDBBrunno Gomes
 
Domain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHDomain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHGiovanni Bassi
 

Semelhante a NHibernate (20)

Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...
Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...
Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Ja...
 
DDD > Experiências
DDD > ExperiênciasDDD > Experiências
DDD > Experiências
 
Palestra cbq
Palestra cbqPalestra cbq
Palestra cbq
 
Linguagem R
Linguagem RLinguagem R
Linguagem R
 
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
Estrutura de dados - Aula de Revisão (Linguagem C/C++, Função, Vetor, Matriz,...
 
Estrutura de Dados - Aula de revisão de c na prática
Estrutura de Dados - Aula de revisão de c na práticaEstrutura de Dados - Aula de revisão de c na prática
Estrutura de Dados - Aula de revisão de c na prática
 
Lógica de programação pascal
Lógica de programação   pascalLógica de programação   pascal
Lógica de programação pascal
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao c
 
Aula5 introducao c
Aula5 introducao cAula5 introducao c
Aula5 introducao c
 
Introdução a linguagem c karen lowhany
Introdução a linguagem c   karen lowhanyIntrodução a linguagem c   karen lowhany
Introdução a linguagem c karen lowhany
 
Estrutura de dados
Estrutura de dadosEstrutura de dados
Estrutura de dados
 
Apostila estrutura de dados 2
Apostila estrutura de dados 2Apostila estrutura de dados 2
Apostila estrutura de dados 2
 
Mongodb workshop cinlug
Mongodb workshop cinlugMongodb workshop cinlug
Mongodb workshop cinlug
 
Pged 03
Pged 03Pged 03
Pged 03
 
Ed1
Ed1Ed1
Ed1
 
Mini-Curso de MongoDB
Mini-Curso de MongoDBMini-Curso de MongoDB
Mini-Curso de MongoDB
 
Palestra2009
Palestra2009Palestra2009
Palestra2009
 
Estruturas
EstruturasEstruturas
Estruturas
 
Aula09 traducaosin110
Aula09 traducaosin110Aula09 traducaosin110
Aula09 traducaosin110
 
Domain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHDomain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BH
 

NHibernate

  • 1. Programação OO com NHibernate Humberto Cardoso Marchezi 2010
  • 2. Programação OO com NHibernate  Agenda  Dia 1: Fundamentos de NHibernate  Para que serve ?  Quais as vantagens ?  O que é mapeamento objeto-relacional ?  Como funciona o mapeamento objeto-relacional no NHibernate ?  Exercícios (Mapeando uma classe simples – apenas propriedades)
  • 3. Programação OO com NHibernate  Agenda  Dia 2: Associações no NHibernate  Como implementar uma associação vários-para-um (simples) ?  Exercício  Como implementar uma associação vários-para-um (posse) ?  Exercício  Como implementar uma associação um-para-vários ?  Exercício
  • 4. Programação OO com NHibernate  Agenda  Dia 3: Associações no Nhibernate e Herança  Como implementar uma associação vários-para-vários ?  Exercício  Herança  Uma Tabela para cada Classe  Exercício  Uma Tabela para Toda a Herança  Exercício
  • 5. Programação OO com NHibernate  Agenda  Dia 4: Objetos de Valor  Objetos de Valor e Entidades  Como implementar um objetos de valor  Exercício
  • 6. Fundamentos de NH  Para que serve ?  Automatizar a relação entre dois mundos:  As tabelas/visões do banco relacional ( dados )  As classes do mundo dos objetos ( domínio do problema ) Modelo de Objetos Modelo de Dados class PessoaFisica table PessoaFisica session select class Documento .SaveUpdate(p); table Documento insert NHibernate update class Endereco session table Endereco remove .Remove(p); class table TipoDocumento TipoDocumento
  • 7. Fundamentos de NH  Para que serve ?  Geração Automática de Comandos SQL TipoDocumento tp = new TipoDocumento(); insert into Geral_TipoDocumento tp.Descricao = “Tipo Doc Qualquer”; ( descricao ) values ( “Tipo Doc Qualquer” ) session.SaveOrUpdate(tp); select TipoDocumento tp = session tp.codTipoDocumento, tp.descricao .Get<TipoDocumento>(12); from Geral_TipoDocumento tp where tp.codTipoDocumento = 12 tp.Descricao = “Outro Tipo Doc”; update Geral_TipoDocumento tp set session.SaveOrUpdate(tp); tp.descricao = “Outro Tipo Doc” where tp.codTipoDocumento = 12 session.Delete(tp); delete Geral_TipoDocumento where tp.codTipoDocumento = 12
  • 8. Fundamentos de NH Ao invés disso (Programação comum) if (nome == string.Empty)  Vantagens { throw new Exception(“nome vazio”);  POO – Abstrair } if (numCPF == null) complexidade das { throw new Exception(“cpf não foi informado”); regras de negócio } ......... Lógica para validar o CPF.......... (Escrever código que if (numCEP == null) parece fácil) { throw new Exception(“CEP não informado”); } Isso (Programação OO) ............. Lógica para validar o CEP ............... PessoaFisica p=new PessoaFisica( ............. Lógica para trazer endereco pelo CEP.. nome, string sql = “insert into Pessoa (nome, cpf, new DocumentoCPF(numCPF), numero, cep, codLogradouro, codBairro, new Endereco(numCEP, codLocalidade, codEstado, codPais) values numEndereco)); (“nome + ”,” + cpf + ”,” + numero + ”,” + cep + ”,” + codLogr................................. session.Save(p); SqlCommand sql = new SqlCommand(sql); .......... Continua e nem cabe aqui o código .......
  • 9. Fundamentos de NH  Vantagens  Essa relação não precisa ser 1 classe = 1 tabela havendo um espaço para flexibilidade entre os dois modelos Modelo de Objetos Modelo de Dados Pessoa TabPesso a Pessoa Pessoa TabDocument o Document Taxa o TabDocument ValorFinanceiro o
  • 10. Fundamentos de NH  Vantagens  Permite que o DBA se concentre na melhor forma de modelar os dados e os Analistas/Programadores se concentrem na melhor forma de representar as entidades e regras do problema a ser modelado
  • 11. Fundamentos de NH  Vantagens  Classes podem ser escritas em C# puro sem qualquer tipo de implementação específica como herdar de classe específica ou public classinterface ImpostoX public class ImpostoX public class ImpostoX { { { protected decimal _valor; protected decimal _valor; protected decimal _valor; protected ImpostoX() { } public ImpostoX() { } public ImpostoX() { } public ImpostoX(decimal valor) public decimal Valor { public void AtribuirValor { get { return _valor; } (decimal valor) _valor = valor; set { _valor = value; } { } } _valor = valor; public decimal Valor } } { public decimal ObterValor( ) get { return _valor; } { } return _valor; } } }
  • 12. Fundamentos de NH  Vantagens  Reuso de código ao invés de copy/paste  Garantia de qualidade: testes unitários  Legibilidade, manutenibilidade, extensibilidade, etc.
  • 13. Fundamentos de NH  O que é mapeamento objeto-relacional ?  Técnica que consiste em traduzir (criar um tipo “de .... - para ... “) entre as classes e suas propriedades no modelo-de-objetos e as tabelas/visões e suas colunas no modelo de dados  No NHibernate esse mapeamento é feito através de arquivos no padrão XML ( *.hbm.xml )  A partir desses arquivos, o NHibernate sabe como gerar os SQLs automatizados para as classes
  • 14. Fundamentos de NH  O que é mapeamento objeto-relacional ? public class TipoHistorico { protected TipoHistorico( ) { } public TipoHistorico (string descricao) { tabela Geral_TipoHistorico _descricao = descricao; } codTipoHistorico int PK protected long _id; public long Id { descricao varchar(50) get { return _id; } set { _id = value; } } protected string _descricao; public string Descricao { get { return _descricao; } set { _descricao = value; } }
  • 15. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? TipoDocumento.cs using System; namespace ControleCorporativo.ControleGeral.DP { public class TipoDocumento { private long _id; public long Id { get { return _id; } set { _id = value; } } private string _descricao; public string Descricao { get { return _descricao; } set { _descricao = value; } } } }
  • 16. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Tabela Geral_TipoDocumento create table Geral_TipoDocumento ( codTipoDocumento INT primary key, descricao varchar(60) )
  • 17. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? TipoDocumento.hbm.xml <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="ControleCorporativo.ControleGeral.DP.TipoDocumento" table="Geral_TipoDocumento"> <id name="Id" column="codTipoDocumento"> <generator class="identity"/> </id> <property name="Descricao" column="descricao" access="field.camelcase- underscore"/> </class> </hibernate-mapping>
  • 18. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ?  Configuração: ( necessárioconfiguração para o NHibernate Criando uma classe de na primeira vez ) using System; using NHibernate.Cfg; namespace SistemaX.Persistencia { public class ConfiguracaoNH { public static Configuration CriarConfiguracao() { Configuration config = new Configuration(); config.Properties["query.substitutions"] = "true 1,false 0"; config.Properties["connection.provider"] = "NHibernate.Connection.DriverConnectionProvider"; config.Properties["dialect"] = "NHibernate.Dialect.MsSql2000Dialect"; config.Properties["connection.driver_class"] = "NHibernate.Driver.SqlClientDriver"; config.Properties["connection.connection_string"] = "server=ColibriSQL2005;database=bdcurso;user id=usr_aluno;"+ "password=aluno;connect timeout=60"; config.AddAssembly("SistemaX.Dominio"); return config; } } }
  • 19. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ?  Criando um singleton para a ISessionFactory vez ) Configuração: ( necessário na primeira (NHibernateHelper.cs) using NHibernate; namespace SistemaX.Persistencia { public class NHibernateHelper { // A ISessionFactory é unica para toda a aplicação e // é responsável por processar todos os mapeamentos // do NHibernate private static readonly ISessionFactory sessionFactory = ConfiguracaoNH.CriarConfiguracao().BuildSessionFactory(); public static ISessionFactory ObterSessaoFactory() { return sessionFactory; } } }
  • 20. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Inserindo // Abre a sessao com o banco ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession(); // Cria um tipo de documento TipoDocumento tp = new TipoDocumento() { Descricao = “Novo Tipo Documento” }; // Inicia Transação ITransaction tx = sessao.BeginTransaction(); // Salva o tipo de documento sessao.Save(tp); // Confirma Transação tx.Commit(); // Fecha a sessão com o banco sessao.Close();
  • 21. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Alterando // Abre a sessao com o banco ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession(); // Cria um tipo de documento TipoDocumento tp = sessao.Get<TipoDocumento>(10); // Inicia Transação ITransaction tx = sessao.BeginTransaction(); // Salva o tipo de documento sessao.Update(tp); // Confirma Transação tx.Commit(); // Fecha a sessão com o banco sessao.Close();
  • 22. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Removendo // Abre uma sessão com o banco ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession(); // Inicia uma transação ITransaction transacao = session.BeginTransaction(); // Recupera um tipo de documento com chave = 10 TipoDocumento tipoDocumento = session.Get<TipoDocumento>(10); // Deletando um tipo de documento session.Delete(tipoDocumento); // Confirma a transação transacao.Commit(); // Fecha a sessão com o banco session.Close();
  • 23. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Consultando (com HQL) // Abre uma sessão com o banco ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession(); // Executa uma consulta em HQL, resultado como lista de objetos string strHQL = “from TipoDocumento tp where tp.Descricao like '%CP%'”; IList<TipoDocumento> lstResultado = session.CreateQuery(strHQL) .List<TipoDocumento>(); string strMensagem = string.Empty; foreach(TipoDocumento tp in lstResultado) { strMensagem += “ Id = “ + tp.Id + “ Desc = “ + tp.Descricao + “n”; } MessageBox.Show(strMensagem); // Fecha a sessão com o banco
  • 24. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Consultando (com HQL) // Abre uma sessão com o banco ISession session = NHibernateHelper.ObterSessaoFactory().OpenSession(); // Executa uma consulta em HQL, resultado como lista de objetos IList<TipoDocumento> lstResultado = (from tp in session.Linq<TipoDocumento>() where tp.Descricao.Contains(“CP”) select tp).ToList(); string strMensagem = string.Empty; foreach(TipoDocumento tp in lstResultado) { strMensagem += “ Id = “ + tp.Id + “ Desc = “ + tp.Descricao + “n”; } MessageBox.Show(strMensagem); // Fecha a sessão com o banco
  • 25. Fundamentos de NHibernate  Como funciona o mapeamento objeto-relacional no NHibernate ? Template de mapeamento <?xml version ="1.0" encoding ="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2 " assembly="[DLL onde está a classe] " namespace="[namespace da classe (using)] "> <class name="[nome da classe] " table="[nome da tabela] " lazy="true"> <id name="[propriedade de id] " column="[chave primária] " type="[nome do tipo na classe] "> <generator class="[ native | identity | sequence | assigned | outros ] "/> </id> <property name="[campo1 da classe] " type="[tipo na classe] " column="[coluna1 na tabela] " accessor ="field.camelcase-underscore " /> <property name="[campo2 da classe] " type="[tipo na classe] " column="[coluna2 na tabela] " accessor ="field.camelcase-underscore " /> <property name="[campo3 da classe] " type="[tipo na classe] " column="[coluna3 na tabela] " accessor ="field.camelcase-underscore " /> : : : : : : : : : : : : <property name="[campoN da classe] " type="[tipo na classe] " column="[colunaN na tabela]"accessor ="field.camelcase-underscore " /> </class> </hibernate-mapping >
  • 26. Fundamentos de NHibernate  Exercício  Dada a classe Pessoa ( em pseudo código ) e a tabela Pessoa abaixo, criar uma mini- aplicação web de cadastro utilizando NHibernate.  class Orgao { public long Id {get;set;}; public string Descricao {get;set;}; }  create table Orgao (codOrgao INT primary key, descricao varchar(50) NOT NULL )  Campos Incluir txtDesc da mini aplicação web: r Nome:  txtId Remov Id: er  txtId txtDesc Alterar r txtDesc Pesquisa  Id: Nome: r r ListBox
  • 28. Associações no NHibernate  Convenção para notação de classes em C#.NET TipoDocumento.cs (Completo) TipoDocumento.cs (Simplificado) using System; public class TipoDocumento namespace ControleCorporativo.ControleGeral.DP { { public long Id { get; set; } public class TipoDocumento public string Descricao {get; { set; } private long _id; } public virtual long Id { get { return _id; } protected set { _id = value; } } private string _descricao; public string Descricao { get { return _descricao; } set { _descricao = value; } } }
  • 29. Associações no NHibernate  Como implementar mapeamento sem associacões ? C#.NET SQL public class Orgao create table Orgao { ( public long Id { get; set; } codOrgao INT primary key, public string Descricao {get; set;} descricao varchar(50) } ) Orgao.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="SistemaX.Dominio.Orgao" table="Orgao"> <id name="Id" column="codOrgao"> <generator class="identity"/> </id> <property name="Descricao" column="descricao" access="field.camelcase-underscore"/> </class> </hibernate-mapping>
  • 30. Associações no NHibernate  Associação vários-para-um (Associação) C#.NET SQL public class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50), public Orgao Lotacao { get; set; } codOrgao INT } ) public class Orgao create table Orgao { ( public long Id { get; set; } codOrgao INT primary key, public string Descricao { get; set; } descricao varchar(50) } )
  • 31. Associações no NHibernate  Associação vários-para-um (Associação) Pessoa.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[assembly]"> <class name="SistemaX.Dominio.Pessoa" table="Pessoa"> <id name="Id" column="codPessoa"> <generator class="identity" /> </id> <property name="Nome" column="nome" access="field.camelcase-underscore"/> <many-to-one name=”Lotacao” class="Orgao" column=”codOrgao” access="field.camelcase-underscore"/> </class> </hibernate-mapping>
  • 32. Associações no NHibernate  Associação vários-para-um (Associação) Exemplo de código C# para alteração do Orgão onde uma Pessoa esta lotada: ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession(); ITransaction trans = sessao.BeginTransaction(); // Obtem um orgao do banco-de-dados Orgao orgao = sessao.Get<Orgao>((long)45); // Cria uma nova pessoa Pessoa p = sessao.Get<Pessoa>((long)70); p.Lotacao = orgao; // Salva a pessoa sessao.Save(p); trans.Commit(); sessao.Close();
  • 33. Associações no NHibernate  Exercício (vários-para-um) (associação)  Incluir Pessoa  Nome txtNome Incluir Orgao cmbbxOrgao  Alterar Pessoa  Pelo Id txtIdPessoa Nome txtNome Alterar Orgao cmbbxOrgao  Remover Pessoa  Remove Pelo Id txtIdPessoa r
  • 34. Associações no NHibernate  Associação vários-para-um (composição) C#.NET SQL public class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50), private Endereco _endereco = codEndereco INT new Endereco(); ) public Endereco Endereco { get; } } create table Endereco ( public class Endereco codEndereco INT primary { key, public long Id { get; set; } localidade varchar(50) public string Localidade { get; set; } ) }
  • 35. Associações no NHibernate  Associação vários-para-um (Posse) Pessoa.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[assembly]"> <class name="SistemaX.Dominio.Pessoa" table="Pessoa"> ..................... outros mapeamentos .......................... <many-to-one name=”Endereco” class="Endereco" column=”codEndereco” access="field.camelcase-underscore" cascade="all"/> </class> </hibernate-mapping> Endereco.hbm.xml <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="SistemaX.Dominio.Endereco" table="Endereco"> <id name="Id" column="codEndereco"> <generator class="identity"/> </id> <property name="Localidade" column="localidade" access="field.camelcase- underscore"/> </class>
  • 36. Associações no NHibernate  Associação vários-para-um (Posse) ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession(); ITransaction trans = sessao.BeginTransaction(); Exemplo de código C# para inclusão de Pessoa com Endereco: // Cria uma nova pessoa com Endereco Pessoa p = new Pessoa( ) p.Nome=”Nova Pessoa”; p.Endereco.Localidade = “Anchieta”; sessao.Save(p); Exemplo de código C# de alteração de endereço de uma Pessoa existente no banco: // Alterando a localidade de uma pessoa grvada em banco Pessoa p2 = sessao.Get<Pessoa>((long)70); p2.Endereco.Localidade = “Outra Localidade”; sessao.Update(p); trans.Commit(); sessao.Close();
  • 37. Associações no NHibernate  Exercício (associação vários-para-um)  Incluir Pessoa  Id da Pessoa txtIdPessoa Nome txtNome Localidade txtLocalidade Incluir  Alterar Pessoa  Alterar Id da Pessoa txtIdPessoa Nome txtNome Localidade txtLocalidade  Remover Pessoa  Remove Id da Pessoa txtIdPessoa r
  • 38. Associações no NHibernate  Associação um-para-vários C#.NET SQL public class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50) private IList<Documento> ) _documentos = new List<Documento>(); create table Pessoa_Documento public IList<Documento> Documentos ( { get; } codDocumento INT primary key, } numero varchar(50), codPessoa int ) public class Documento { public long Id { get; set; } public string Numero { get; set; } public Pessoa Pessoa { get; }
  • 39. Associações no NHibernate  Associação um-para-vários Pessoa.hbm.xml <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="SistemaX.Dominio.Pessoa" table="Pessoa"> : : : outros mapeamentos : : : : : <bag name="Documentos" access="field.camelcase-underscore" cascade="all-delete-orphan" inverse="true"> <key column="codPessoa"/> <one-to-many class="SistemaX.Dominio.Documento"/> </bag> </class> </hibernate-mapping> Documento.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[DLL]" namespace="[namespace]"> <class name="DocumentoPessoa" table="Pessoa_DocumentoPessoa" lazy="true"> <id name="Id" column="codDocumentoPessoa" type="Int64"> <generator class="identity" /> </id> <property name="numero" column="numero" type="string" access="field.camelcase-underscore"/> <many-to-one name="relPessoa" class="Pessoa" column="codPessoa" access="field.ca..." not-null="true"/> </class>
  • 40. Associações no NHibernate  Associação um-para-vários Exemplo de código C# para inclusão de Documento em Pessoa Existente no Banco ISession sessao = NHibernateHelper.ObterSessaoFactory().OpenSession(); ITransaction trans = sessao.BeginTransaction(); // Obtem uma pessoa do banco-de-dados Pessoa p = sessao.Get<Pessoa>((long)44); // Adiciona um documento na Pessoa Documento d = new Documento() { Numero = “00009900” , Pessoa = p }; p.Documentos.Add(d); // Altera o primeiro documento da Pessoa p.Documentos[0].Numero = “000900”; // Remove o terceiro documento da Pessoa p.Documentos.Remove( p.Documentos[2] ); // Salva a pessoa e todas alterações nos documentos de uma só vez sessao.Update(p); trans.Commit(); sessao.Close();
  • 41. Associações no NHibernate  Exercício (associação um-para-vários)  Incluir Documento  Id da Pessoa txtIdPessoa Desc. Doc. txtDescrDocumento Incluir  Alterar Documento  Alterar Id da Pessoa txtIdPessoa Id do Doc. txtIdDoc Desc.doc. txtDescrDocumento  Remover Documento Remove  r Id da Pessoa txtIdPessoa Id do Doc. txtIdDoc
  • 43. Associações no NHibernate  Associação vários-para-vários C#.NET SQL public class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50) } ) create table PessoaTarefa ( codPessoa INT, codTarefa INT ) public class Tarefa create table Tarefa { ( public long Id { get; set; } codDocumento INT primary key, public string Descricao {get; set;} descricao varchar(50), public IList<Pessoa> Pessoas {get; set;} codPessoa INT } )
  • 44. Associações no NHibernate  Associação vários-para-vários Tarefa.hbm.xml <?xml version="1.0" encoding="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="SistemaX.Dominio.Tarefa" table="Tarefa" lazy="true"> <id name="Id" column="codTarefa"> <generator class="identity"/> </id> <property name="Descricao" column="descricao" access="field.camelcase-underscore"/> <bag name="Pessoas" table="Pessoa_Tarefa" access="field.camelcase-underscore" lazy="true" inverse = "false" cascade="all"> <key column="codTarefa"/> <many-to-many class="SistemaX.Dominio.Pessoa" column="codPessoa"/> </bag> </class> </hibernate-mapping>
  • 45. Associações no NHibernate  Exercício (associação Vários-para-vários)  Incluir Tarefa  Incluir Nome txtDescricao  Alterar Tarefa  Alterar Pelo Id txtIdTarefa Descricao txtDescricao  Remover Tarefa  Remove Pelo Id txtIdTarefa r  Incluir Pessoa na Tarefa  Tarefa txtIdTarefa Incluir Pessoa txtIdPessoa  Remover Pessoa da Tarefa  Tarefa txtIdTarefa Remove Pessoa txtIdPessoa r
  • 46. Associações no NHibernate  Template de mapeamento: (Resumo) Template de classe using System; namespace AlgumNamespace { public class AlgumaClasse { private long _id; public virtual long Id { get { return this._id; } protected set { this._id = value; } } protected tipo _campo; public virtual tipo Campo { get { return this._campo; } set { this._campo = value; } } protected OutraClasse _associacao; public virtual OutraClasse Associacao { get { return this._associacao; } set { this._associacao = value; } } protected IList<MaisOutraClasse> _associacaoLista; public virtual IList<MaisOutraClasse> AssociacaoLista { get { return this._associacaoLista; } set { this._associacaoLista = value; } } } }
  • 47. Associações no NHibernate  Template de mapeamento: (Resumo) Template de mapeamento <?xml version ="1.0" encoding ="utf-8" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2 " assembly="[DLL da classe] " namespace ="[namespace] "> <class name="[nome da classe] " table="[nome da tabela] " lazy="true"> <id name="[propriedade de id] " column="[chave primária] " type="[tipo na classe] "> <generator class="[ native | identity | sequence | assigned | outros ] "/> </id> <property name="[campo da classe] " type="[tipo do campo] " column="[coluna na tabela] " accessor ="field.camelcase- underscore " /> <many-to-one name="[assoc. da classe] " class="[tipo da assoc.] " column="[chaveFK] " cascade ="[none | all | save-update] " access ="field.camelcase-underscore" /> <bag name="[lista na classe] " lazy="true" cascade ="[ all-delete-orphan | save-update | none ] " inverse="true" access ="field.camelcase-underscore"> <key column="[chave FK na tabela filho] "/> <one-to-many class="[tipo de cada elemento na lista1] "/> </bag> <bag name="[lista da classe] " table="[tabela agregada da associac.] " lazy="true" access="field.camelcase-underscore" cascade ="[ all-delete-orphan | save-update | none ] "> <key column="[chave FK para a tabela filho] "/> <many-to-many class="[tipo de cada elemento na listaN+1] " column="[chave FK para a tabela pai] "/> </bag> </class> </hibernate-mapping >
  • 48. Herança  Estrutura em árvore composta por uma classe pai (genérica) e as classes filhas (específicas)  Herança de classe pode ter várias formas no Modelo de Dados Uma tabela para toda a hierarquia de classes  Uma tabela por classe  Uma tabela cada cada classe concreta 
  • 49. Herança  Uma tabela para toda a hierarquia  Modelo de Classe Modelo de Dados public abstract class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50), } sexo char, objetoSocial varchar(50), public class PessoaFisica : Pessoa tipoPessoa char { ) public char Sexo { get; set; } } public class Pessoa Juridica : Pessoa { public string ObjetoSocial { get; set; } }
  • 50. Herança  Uma tabela para toda a hierarquia Pessoa.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio"> <class name="SistemaX.Dominio.Pessoa" table="Pessoa" lazy="true"> <id name="Id" column="codPessoa" type="Int64"> <generator class="identity" /> </id> <discriminator column=”tipoPessoa” type=”char”/> <property name="Nome" column="nome" type="string" access="field.camelcase-underscore"/> </class> </hibernate-mapping> PessoaJuridica.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio"> <subclass name=”PessoaJuridica” discriminator-value=”j” extends="Pessoa"> <property name=”CNPJ” column=”cnpj” access="field.camelcase-underscore"/> </subclass> </hibernate-mapping> PessoaFisica.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio"> <subclass name=”PessoaFisica” discriminator-value=”f” extends="Pessoa"> <property name=”CPF” column=”cpf” access="field.camelcase-underscore"/> </subclass> </hibernate-mapping>
  • 51. Herança  Uma tabela por classe  Modelo de Classe Modelo de Dados public abstract class Pessoa create table Pessoa { ( public long Id { get; set; } codPessoa INT primary key, public string Nome { get; set; } nome varchar(50), } ) public class PessoaFisica : Pessoa create table PessoaFisica { ( public char Sexo { get; set; } codPessoa INT primary key, } sexo char(50), ) public class Pessoa Juridica : Pessoa { create table PessoaJuridica public string ObjetoSocial { get; ( set; } codPessoa INT primary key, } objetoSocial varchar(50), )
  • 52. Herança  Uma tabela por classe Pessoa.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" > <class name="SistemaX.Dominio.Pessoa" table="Pessoa" lazy="true"> <id name="Id" column="codPessoa" type="Int64"> <generator class="identity" /> </id> <property name="Nome" column="nome" type="string" access="field.camelcase- underscore"/> </class> </hibernate-mapping> PessoaJuridica.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio"> <joined-subclass name=”PessoaJuridica” table=”PessoaJuridica” lazy="true" extends="Pessoa"> <key column=”codPessoa”/> <property name=”ObjetoSocial” column=”objetoSocial” access="field.camelcase-underscore"/> </joined-subclass> </hibernate-mapping> PessoaFisica.hbm.xml <?xml version="1.0" ?> <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="SistemaX.Dominio" namespace="SistemaX.Dominio"> <joined-subclass name=”PessoaFisica” table=”PessoaJuridica” lazy="true" extends="Pessoa"> <key column=”codPessoa”/> <property name=”Sexo” column=”sexo” access="field.camelcase-underscore"/> </joined-subclass> </hibernate-mapping>
  • 53. Herança Exercício (Herança -> 1 tabela para a hierarquia ) Escrever um mapeamento NHibernate para a herança de documentos abaixo: public class Documento { public long Id { get; set; } create table Documento public string Numero { get; set; } ( } codDocumento INT primary public class DocumentoCI : Documento key, { numero varchar(50), public string Estado { get; set; } estado varchar(50), } categoria varchar(50), public class DocumentoCNH : Documento tipoDocumento varchar(50) { ) public string Categoria { get; set; } } Fazer uma tela web de consultar objetos via HQL: txtHQL btExecutar listBoxResultado
  • 54. Herança Exercício (Herança ->1 tabela por classe) public abstract class Pessoa create table Pessoa { ( codPessoa INT primary key, public long Id { get; set; } ... ... ) } create table PessoaFisica public class PessoaFisica : Pessoa ( { codDocumento INT, public string Sexo { get; set; } sexo varchar(50) } ) public class PessoaJuridica : Pessoa create table PessoaJuridica ( { codDocumento INT, public string ObjetoSocial { get; set; } objetoSocial varchar(50) } ) Utiliar a mesma tela web de consulta para verificar os mapeamentos txtHQL btExecutar listBoxResultado
  • 56. Objetos de Valor e Entidades  Entidade:  Toda classe cujo objeto precisa de um Id para identif.  Normalmente esta mapeada para 1 ou mais tabelas  Ex: Pessoa, Logradouro, InscricaoCadastral  Objeto de Valor:  Também é classe mas não possui Id de identificação  Representa um conceito importante do negócio  É imutável, não pode ser alterado, apenas subtituído  Ex: Dinheiro (valor + unid. Ref.), Endereco (alguns casos)
  • 57. Objetos de Valor e Entidades  Exemplo:  Modelo de Dados Modelo de Classes public class Taxa create table Taxa { ( public long Id { get; set; } codTaxa INT primary key, public string Descricao { get; set; } descricao varchar(50), public UnidadeReferencia codUnidadeReferencia INT, UnidadeReferencia valorTaxa numeric(12,4) { get; set; } ) public decimal ValorTaxa { get; set; } } create table UnidadeReferencia ( public class UnidadeReferencia codUnidadeReferencia INT primary { key, public long Id { get; set; } descricao varchar(50) public string Descricao { get; set; } ) }
  • 58. Objetos de Valor e Entidades  Exemplo: (Funciona, mas vamos pensar melhor ... )  Modelo de Dados Modelo de Classes public class Taxa create table Taxa { ( public long Id { get; set; } codTaxa INT primary key, public string Descricao { get; set; } descricao varchar(50), public UnidadeReferencia codUnidadeReferencia INT, UnidadeReferencia valorTaxa numeric(12,4) { get; set; } ) public decimal ValorTaxa { get; set; } } create table UnidadeReferencia ( public class UnidadeReferencia codUnidadeReferencia INT primary { key, public long Id { get; set; } descricao varchar(50) public string Descricao { get; set; } ) }
  • 59. Objetos de Valor e Entidades  Exemplo: (Vamos pensar melhor ... )  Modelo de Dados Modelo de Classes create table Taxa ( codTaxa INT primary key, descricao varchar(50), codUnidadeReferencia INT, Essas duas colunas aparecem juntas valorTaxa numeric(12,4) em várias tabelas sugerindo um ) conceito importante de valor financeiro. create table UnidadeReferencia ( codUnidadeReferencia INT primary key, descricao varchar(50) )
  • 60. Objetos de Valor e Entidades  Exemplo: ( Incluir conceito de negócio )  Modelo de Dados Modelo de Classes create table Taxa public class Taxa ( { codTaxa INT primary key, public long Id { get; set; } descricao varchar(50), public string Descricao { get; set; } codUnidadeReferencia INT, public ValorFinanc Valor { get; set; } valorTaxa numeric(12,4) } ) public class ValorFinanc { public ValorFinanc (UnidadeReferencia uf, decimal v) create table public UnidadeReferencia { get; } UnidadeReferencia public decimal Valor { get; } ( public ValorFinanc static Adicionar( ValorFinanc fator1, codUnidadeReferencia ValorFinanc fator2, UnidadeReferencia result); INT primary key, public ValorFinanc static Subtr( ValorFinanc subtraendo, descricao varchar(50) ValorFinanc subtrator, UnidadeReferencia result); ) public ValorFinanc Conversao(UnidadeReferencia result); } public class UnidadeReferencia { public long Id { get; set; } public string Descricao { get; set; } }
  • 61. Objetos de Valor e Entidades  Exemplo: ( Incluir conceito de negócio )  Mapeamento da classe Taxa <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="[DLL]" namespace="[namespace]"> <class name="Taxa" table="Taxa" lazy="true"> <id name="Id" column="codTaxa" type="Int64"> <generator class="identity"/> </id> <property name=“Descricao" type="String" column="descricao" not-null="true" accessor="field.camelcase-underscore" /> <component name=“Valor” class=“ValorFinanc”> <property name=“Valor” type=“String” column=“valorTaxa”/> <many-to-one name=“UnidadeReferencia” class=“UnidadeReferencia” column=“codUnidadeReferencia”/> </component> </class> </hibernate-mapping>
  • 62. Exercício Mapear a classe PessoaEspecial class PessoaEspecial create table PessoaEspecial { ( public long Id { get; set; } codPessoaEspecial INT primary public long Nome { get; set; } key, public EnderecoEspecial Endereco nome varchar(50), { get; } localidade varchar(50), } numero varchar(50) ) class EnderecoEspecial { public string Localidade { get; set; } public string Numero { get; set; } } Testar a inclusão e a consulta de uma pessoa especial em C#
  • 63. Observações  Projeto Fluent Nhibernate permite escrever mapeamentos em C# 1. <?xml version="1.0" encoding="utf-8" ?> 2. <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" 3. namespace="QuickStart" assembly="QuickStart"> 4. 1. public class CatMap : ClassMap<Cat> 5. <class name="Cat" table="Cat"> 2. { 6. <id name="Id"> 3. public CatMap() 7. <generator class="identity" /> 4. { 8. </id> 5. Id(x => x.Id); 9. 6. Map(x => x.Name) 10. <property name="Name"> 7. .WithLengthOf(16) 11. <column name="Name" length="16" not-null="true" /> 8. .Not.Nullable(); 12. </property> 9. Map(x => x.Sex); 13. <property name="Sex" /> 10. References(x => x.Mate); 14. <many-to-one name="Mate" /> 11. HasMany(x => x.Kittens); 15. <bag name="Kittens"> 12. } 16. <key column="mother_id"/> 13. } 17. <one-to-many class="Cat"/> 18. </bag> 19. </class> 20. </hibernate-mapping>
  • 64. Observações  Consultas em Linq-to-NHibernate ist<TipoDocumento> lstResultado = (from tp in session.Linq<TipoDocumento>() where tp.Descricao.Contains(“CP”) select tp).ToList();  Recursos geo-espaciais (MsSQLSpatial, PostGIS) // Encontra um país localizado em uma coordenada Country country = session.CreateCriteria(typeof(Country)) .Add(SpatialExpression.Contains("Boundaries", new Point(-70.40, -33.24))) .UniqueResult() as Country; // Encontra as cidades de uma área exceto aquelas localizadas em algumas coords. Town[] towns = Town.FindAll( SpatialExpression.Filter("Boundaries", new Envelope(-70, -68, -32, -34)), Expression.Not(SpatialExpression.Contains("Boundaries", new Point(-70.40, -33.24))) );
  • 65. Observações  Vantagens só aparecem com Programação OO Isso Ao invés disso Pessoa p = new Pessoa( if ((strNome == null)||(strNome == string.Empty)) strNome, { .....Erro ... } new DocumentoCPF(strCPF), if ((strCPF == null)||(strCPF == string.Empty)) new Endereco(strCEP)); { ... Erro ... } session.SaveOrUpdate(p); if ((strCEP == null)||(strCEP == string.Empty)) { ... Erro ... } IList<Pessoa> lstPessoas = ... consulta para achar ... outra pessoa com ... mesmo nome e CPF if (lstPessoas.Count > 0) { ..... Erro ......... } CEP cep = ... consulta de CEP pelo numero if (cep == null ) { ........ Erro ....... } Localidade localidade = cep.Localidade; Pessoa p = new Pessoa( ); p.Nome = strNome; p.Documentos.Add(new DocumentoCPF(strCPF)); p.Endereco.Localidade = localidade; session.SaveOrUpdate(p);
  • 66. Perguntas Contacte o autor, se preferir ... http://www.linkedin.com/in/hcmarchezi ● http://hcmarchezi.blogspot.com.br/ ●