Recuperando objetos com NHibernate Criterias - Revista .net Magazine 104
Artigos .NET Recuperando objetos com NHibernate Criterias - Revista .net Magazine 104
NHibernate Criterias
O NHibernate é um framework ORM extremamente versátil com diversos pontos de extensibilidade que pode ser vista nas diversas opções que temos de mapeamento, gerenciamento de sessão e consultas . No que tange as consultas temos opções como, por exemplo, o SQL Nativo, HQL, Criterias e o recente QueryOver. Hoje focaremos nos recursos para realizações de consultas via Criteria, abordando desde consultas simples envolvendo uma única tabela à consultas mais complexas, com agrupamentos, sumas e outras funções. Para isso, faremos uma introdução rápida sobre as consultas no NHibernate, demonstrando como executar SQLs e HQLS e realizar o parse para objetos de domínio. Veremos também os conceitos fundamentais das Criterias e um exemplo onde teremos uma entidade Pedido relacionada com diversos Itens, que servirá de base para criarmos nossos exemplos de consultas.
Este tema é útil a todos os projetos que tenham a necessidade de recuperação de dados através do NHibernate, possibilitando que o leitor conheça as principais formas de recuperação de dados e domine os recursos fornecidos pelas Criterias do NHibernate.
O NHibernate é extremamente versátil e nos fornece diversas opções para recuperação de dados, sendo elas:
· SQL – Execução de queries utilizando SQL nativo.
· HQL – Execução de queries utilizando Hibernate Query Languag.
· Criterias – Execução de queries utilizando a API de Criterias do NH, baseada no pattern Fluent Interface.
· QueryOver – Execução de queries a partir expressões Lambda.
O uso de SQL é a opção mais básica e provavelmente a menos adequada ao ambiente ORM, pois inserindo código SQL na nossa aplicação estamos correndo o risco de sofrer problemas de compatibilidade de bases de dados caso seja necessário rodar a aplicação para outro SGDB. Além disso, torna a manutenção da aplicação mais difícil e suscetível a erros. Podemos ver um exemplo de uso de SQL na Listagem 1. Observe na linha 3 que é preciso adicionar o tipo da entidade para que o NHibernate realize automaticamente o parse do resultado da consulta para o tipo especificado no AddEntity.
Listagem 1. Exemplo de consulta com SQL nativo no NHibernate
01            ISession sessao = NHSessionFactoryManager.
GetSessionFactory().OpenSession();
02            ISQLQuery query = sessao.CreateSQLQuery
("select id, nome, idade,
sexo from cliente");
03            query.AddEntity(typeof(Cliente));
04            IList<Cliente> listaConsulta =
query.List<Cliente>();
05            return listaConsulta;
O uso de HQL não tem o problema da compatibilidade, pois utilizamos uma linguagem intermediária do próprio NHibernate, ficando o mesmo responsável por realizar o parse para o SQL nativo do SGDB usado na aplicação. Por outro lado, temos ainda o problema da manutenção, por termos as famosas "magic strings" no nosso código. Na Listagem 2 podemos ver um exemplo de consulta com o HQL, em que não precisamos do AddEntity, pois o NHibernate já realiza o parse automaticamente para o tipo especificado no generic do List. Outro item a observar é que simplesmente executamos "From Cliente", entendendo que desejamos a instância completa dos objetos Cliente.
Listagem 2. Exemplo de consulta com HQL no NHibernate
01            ISession sessao =
NHSessionFactoryManager.GetSessionFactory().OpenSession();
02            IQuery query = sessao.CreateQuery("from Cliente");
03            IList<Cliente> listaConsulta =
04            return listaConsulta;
Melhorando as nossas opções nós temos as criterias que tratam-se de objetos de consulta que nos permitem determinar os parâmetros, restrições e características das consultas que desejamos usar, só que através de objetos fortemente tipados. Com isso, não temos as "magic string" para elaboração do código SQL. Um exemplo de consulta com Criteria pode ser visto na Listagem 3, onde podemos ver que não precisamos de códigos em texto, fazendo a operação de consulta através do próprio objeto Criteria. Neste caso só será necessário usar strings quando precisarmos referenciar alguma propriedade para realizar filtros, agrupamentos, ordenação etc.
Listagem 3. Exemplo de consulta com Criteria no NHibernate
02            ICriteria criteria = sessao.CreateCriteria<Cliente>();
criteria.List<Cliente>();
Por fim temos a opção mais recente, QueryOver, que foi introduzido no NHibernate a partir da versão 3.0 e combina extension methods e expressões lambda para eliminar de vez as strings de nossas consultas, permitindo que propriedades sejam especificadas através delas. Na Listagem 4 podemos ver um exemplo.
Listagem 4. Exemplo de consulta com QueryOver no NHibernate
02            IQueryOver<Cliente> queryOver =
sessao.QueryOver<Cliente>().Where
(x => x.Sexo == "Masculino");
queryOver.List<Cliente>();
Sendo assim, podemos ver que as opções mais indicadas são o uso de Criterias ou QueryOver. Hoje focaremos no uso do Criteria. Vale ressaltar que é importante conhecer as demais formas via SQL e HQL, pois podem haver requisitos no projeto em que os mesmos sejam mais adequados. Em especial as consultas via SQL são mais comuns de serem utilizadas em aplicações legadas, que não possuem um modelo muito bem definido e passam por um momento de transição para ORM.
Entendendo o ICriteria do NH
Como podemos notar nos exemplos anteriores, o Criteria do NHibernate implementa uma interface chamada ICriteria e pra criarmos uma criteria precisamos invocar o método CreateCriteria de um ISession. Um objeto Criteria possui os seguintes métodos:
· Add – Este método recebe um objeto ICriterion e é responsável pela inclusão de novas condições na criteria.
· AddOrder – Este método recebe um objeto Order como parâmetro, com a indicação da direção da ordenação e da propriedade a ser ordenada.
· CreateAlias – Permite a criação de um alias para uma associação do objeto principal da criteria.
· CreateCriteria – Permite que seja criada uma nova criteria referente a um objeto associado ao objeto da criteria principal.
· List – Executa a criteria transformando a mesma em código SQL e retornar o resultado em uma lista de objetos.
· SetFetchMode – Permite determinarmos uma estratégia de fetch para uma determinada associação do objeto principal da criteria.