O documento fornece uma introdução ao NHibernate como ferramenta de ORM alternativa. Discute as principais capacidades do NHibernate, como mapeamento de objetos para tabelas de banco de dados, suporte a vários bancos de dados e lazy loading. Também apresenta alguns padrões de projeto comuns em ORM como Active Record e Data Mapper.
2. Introdução ao NHibernate como ferramenta
de O/RM alternativa
Principais capacidades
Comparativo com outros O/RMs
Projectos relacionados
Q&As a qualquer altura
Copyright (c) Ricardo Peres 2010
3. O que é o NHibernate?
Um O/RM carrega dados de tabelas de bases de dados
para objectos .NET e vice-versa
Com o NHibernate, focamos-nos nas classes, não na
base de dados – até pode ser gerada para nós
Construído pela comunidade, inspirado pelo Java
Hibernate
O que o NHibernate não é?
Uma framework de desenvolvimento genérica
Um API de regras de negócio
Uma ferramenta de ETL ou inserções em massa
Copyright (c) Ricardo Peres 2010
4. Independente da base de dados
As tabelas são geradas e actualizadas a partir das classes
Não requer classes ou interfaces base (POCO)
Suporta uma abordagem Domain-Driven Design
Lazy loading de entidades associadas, colecções e
propriedades
Detecção automática de alterações nas entidades
SQL ou stored procedures podem ser usados em todas as
operações
Múltiplos geradores de chaves primárias
Muitas opções para controlo de concorrência
API extensível
Open source
Baseado em Design Patterns
Copyright (c) Ricardo Peres 2010
6. Domain-Driven Design:
An approach to developing software for complex
needs by deeply connecting the implementation to
an evolving model of the core business concepts
OR/M:
A programming technique for converting data
between incompatible type systems in relational
databases and object-oriented programming
languages
Wikipedia
Copyright (c) Ricardo Peres 2010
7. Active Record:
An object that wraps a row in a database table or view, encapsulates the
database access, and adds domain logic on that data
Association Table Mapping:
Saves an association as a table with foreign keys to the tables that are linked by
the association
Class Table Inheritance:
Represents an inheritance hierarchy of classes with one table for each class
Concrete Table Inheritance:
Represents an inheritance hierarchy of classes with one table per concrete class
in the hierarchy
Data Mapper:
A layer of Mappers that moves data between objects and a database while
keeping them independent of each other and the mapper itself
Dependent Mapping:
Has one class perform the database mapping for a child class
Martin Fowler, Patterns of Enterprise Application Integration
Copyright (c) Ricardo Peres 2010
8. Domain Model:
An object model of the domain that incorporates both behavior and data
Embedded Value:
Maps an object into several fields of another object's table
Foreign Key Mapping:
Maps an association between objects to a foreign key reference between tables
Identity Field:
Saves a database ID field in an object to maintain identity between an in-
memory object and a database row
Identity Map:
Ensures that each object gets loaded only once by keeping every loaded object
in a map. Looks up objects using the map when referring to them
Inheritance Mappers:
A structure to organize database mappers that handle inheritance hierarchies
Martin Fowler, Patterns of Enterprise Application Integration
Copyright (c) Ricardo Peres 2010
9. Lazy Load:
An object that doesn't contain all of the data you need but knows how to get it
Metadata Mapping:
Holds details of object-relational mapping in metadata
Mapper:
An object that sets up a communication between two independent objects
Optimistic Offline Lock:
Prevents conflicts between concurrent business transactions by detecting a
conflict and rolling back the transaction
Pessimistic Offline Lock:
Prevents conflicts between concurrent business transactions by allowing only
one business transaction at a time to access data
Query Object:
An object that represents a database query
Martin Fowler, Patterns of Enterprise Application Integration
Copyright (c) Ricardo Peres 2010
10. Single Table Inheritance:
Represents an inheritance hierarchy of classes as a single table that has
columns for all the fields of the various classes
Unit of Work:
Maintains a list of objects affected by a business transaction and coordinates
the writing out of changes and the resolution of concurrency problems
Value Object:
A small simple object, like money or a date range, whose equality isn't based
on identity
Martin Fowler, Patterns of Enterprise Application Integration
Copyright (c) Ricardo Peres 2010
11. DB2
Ingres
PostgreSQL 7+
MySQL 3+
Oracle 8+
Sybase Adaptive Server Enterprise
Sybase Adaptive Server Anywhere
SQL Server 7+ (including Azure)
Firebird
SQLLite
Ingres 3+
Azure
Genérica (SQL 99)
Bases de dados personalizadas
Copyright (c) Ricardo Peres 2010
12. Ficheiros HBM.XML
Classes são POCO, sem referências ao NHibernate
Podem ou não ser incluídos como embedded resources
Atributos
São aplicados atributos nas classes e propriedades
Fluent NHibernate
Classes são POCO, sem referências ao NHibernate
API fluente
As entidades não são tabelas e as propriedades não são
colunas!
O NHibernate constroi o modelo em memória e pode gerar os
scripts DDL de criação
Copyright (c) Ricardo Peres 2010
13. O NHibernate suporta uma abordagem
model-first (primeiro as classes, depois
a BD)
Nesta abordagem, a persistência é
apenas um aspecto, o modelo é
simplesmente POCO, sem preocupações
de como os dados vão ser persistidos
Alguns conceitos são: entidades (com
chave) e valores (sem chave), agregados
e associações
Copyright (c) Ricardo Peres 2010
14. Table per Class Hierarchy (discriminator + subclass)
Uma tabela contém todas as colunas para todas as sub-classes
Classes diferentes são distinguidas por uma coluna discriminatória
Table per Subclass (joined-subclass)
Uma tabela para cada classe mãe e uma para cada sub-classe
A tabela para a classe mãe contém as colunas partilhadas
Table per Concrete Class (union-subclass)
Uma tabela para cada classe concreta
Cada tabela contém todas as colunas de todas as sub-classes
As chaves nunca podem ser iguais
Misto (join)
Copyright (c) Ricardo Peres 2010
16. One to One
Uma entidade em cada
extremo
One to Many / Many to One
Colecção num extremo,
entidade no outro
Many to Many
Colecção em ambos os
extremos
Any / Many to Any
Não é preciso uma classe
base, apenas uma
propriedade conhecida
Ternary
Muitos para um ou um para
muitos ou muitos para
muitos onde o indexador é
uma entidade
Property
Array
Primitive Array
Bag
Não ordenado com repetição
Id Bag
Identificador por relação
List
Lista ordenada com uma coluna
indexadora de tipo inteiro
Set
Sem repetição de elementos
Map
Elementos ordenados indexados
por uma coluna de qualquer tipo,
incluindo entidades
Copyright (c) Ricardo Peres 2010
17. Gerador Propósito
Increment Independente da BD
Identity SQL Server, MySQL, DB2, Sybase
Sequence Oracle, PostgreSQL, DB2, Firebird
Hi / Lo Independente da BD, precisa de uma tabela
especial
Sequence Hi / Lo Precisa de uma tabela especial
Native Identity, Sequence or Hi / Lo, dependendo
da BD
UUID String GUID, independente da BD
GUID GUID, independente da BD
GUID Comb GUID, independente da BD
Assigned Independente da BD
Foreign Entidade um para um relacionada é a chave
18. Join fetching
É usado um JOIN para obter as
entidades associadas
Select fetching
É usado um segundo SELECT para
obter as entidades seleccionadas
Subselect fetching
É usado um segundo SELECT para
obter as entidades seleccionadas
Lazy collection fetching
A colecção é carregada como um
todo quando é acedida
Extra-lazy collection fetching
Cada um dos elementos de uma
colecção é carregado da BD
quando acedido
Proxy fetching
Uma entidade associada é
carregada quando uma das suas
propriedades não chave é acedida
Lazy properties
Uma propriedade individual é
carregada quando acedida (para
CLOBs ou BLOBs)
Copyright (c) Ricardo Peres 2010
19. As session factories (ISessionFactory) são
criadas por objectos Configuration (um por
aplicação)
As sessões são criadas por session factories
Tipicamente apenas uma session factory é
necessária, mas podem ser criadas várias, a
apontar para BDs diferentes
As session factories são pesadas, contêm
todo o modelo
Thread-safe
Copyright (c) Ricardo Peres 2010
20. Todo o acesso à BD é feito através de sessões (pattern
Unit of Work)
Dois tipos de sessões:
Normal (ISession)
Stateless (IStatelessSession):
Não suporta lazy loading
Não reconhece as alterações
Não levanta eventos
Não usa a cache
As conexões à BD apenas são abertas quando necessário
São leves e não thread-safe
Todas as operações são feitas numa sessão
As entidades carregadas por uma sessão estão presas a
ela, mas podem ser desligadas e ligadas a outra
Copyright (c) Ricardo Peres 2010
21. Get / Load: carregar uma entidade / proxy
Refresh: refrescar uma entidade
Save / Update / SaveOrUpdate: guardar uma entidade
SaveOrUpdateCopy: igual a SaveOrUpdate, mas
funciona com entidades não persistidas
Merge: copia o estado de uma entidade não
persistida para uma entidade persistida com o
mesmo id
Persist: torna uma entidade persistente
Delete: apagar uma entidade
Replicate: guardar uma entidade numa nova BD
Lock / Unlock: bloquear / desbloquear uma entidade
Evict / Clear: remover uma entidade / todas as
entidades da cache de primeiro nível
Copyright (c) Ricardo Peres 2010
23. ID
Por chave primária
HQL
Independente da BD, similar a SQL
mas object-oriented
Criteria API
Usa objectos para representar as
condições de filtragem, projecções,
ordenamento, joins, etc (Query
Object pattern)
Por Exemplo
Dado uma entidade exemplo com
alguns valores nas suas
propriedades, procura entidades
similares
Query Over
Idêntico ao Criteria API mas usando
expressões LINQ
Named Queries
Queries pré-compiladas, HQL ou SQL
LINQ
Querying fortemente tipado
SQL
SQL
NHibernate Search
Integração com Lucene.NET
Copyright (c) Ricardo Peres 2010
25. Por Exemplo
Cat example = new Cat {Name =
“Felix”};
var cats =
session.CreateCriteria<Cat>().Add(
Example.Create(example)).List<Cat
>();
By Id
var cat = session.Get<Cat>(1);
var catProxy =
session.Load<Cat>(1);
Named Queries SQL
var cats =
session.CreateSQLQuery(“SELECT *
FROM cat WHERE id =
1”).List<Cat>();
var cats =
session.GetNamedQuery(“GetCats").S
etParameter(“name",
“Felix”).List<Cat>();
Copyright (c) Ricardo Peres 2010
26. NHibernate Search
var cats =
searchSession.CreateFullTextQuery
<Cat>(“Id:1").List<Cat>();
Multi Criteria / Multi
Query / Futuresvar cats =
session.CreateMultiQuery().Add<C
at>(“from Cat c where c.Name =
‘Felix’”).Add<Cat>(“from Cat c
where c.Name = ‘Tom’”).List();
var cats =
session.CreateMultiCriteria().Add<
Cat>(Restrictions.Eq(“Name”,
“Felix”)).Add<Cat>(Restrictions.Eq(
“Name”, “Tom”)).List();
var futureCats =
session.CreateQuery(“from Cat c
where c.Name =
‘Felix’”).Future<Cat>();
var futureCats =
session.CreateCriteria<Cat>(Restri
ctions.Eq(“Name”,
“Felix”)).Future<Cat>();
27. É possível deferir a execução de uma query
para um momento posterior
Podem ser chamadas tanto queries que
devolvem listas como um único elemento:
Future<T> e FutureValue<T>
As queries futuras são todas enviadas em
bloco
Suportadas em SQL Server, SQL Server CE,
MySQL, PostgreSQL e SQLLite
Copyright (c) Ricardo Peres 2010
28. Podem ser especificados filtros para
entidades e colecções
Um filtro pode estar activado (inicialmente
estão desactivados) ou não e ter um ou mais
valores (filtro composto)
Um filtro tem um tipo associado
Especificados nos ficheiros de mapeamento
Copyright (c) Ricardo Peres 2010
30. As alterações em entidades são detectadas
automaticamente, o NHibernate sabe quando um objecto
mudou (snapshot)
O NHibernate também sabe se um objecto veio da BD ou
não
Podem ser usados stored procedures para todas as
operações DML e para carregar entidades (loader, sql-
insert, sql-update, sql-delete, sql-query, sql-delete-all)
Podem ser especificadas regras de cascata para todas as
colecções associadas (all, none, save-update, all-delete-
orphan)
Pode ser usado HQL para todas as operações DML
(INSERT, UPDATE, DELETE)
Copyright (c) Ricardo Peres 2010
31. Todas as operações DML são suportadas
(UPDATE, DELETE, INSERT)
Pode ser especificado o batch-size para
aplicação em bloco
Podem ser gerado SQL apenas para as colunas
modificadas (dynamic-update)
As alterações são aplicadas (flushed) em
determinados momentos
O flushing é configurável por sessão:
No commit (FlushMode.Commit)
Automaticamente (FlushMode.Auto)
Em todas as queries (FlushMode.Always)
Nunca (FlushMode.Never)Copyright (c) Ricardo Peres 2010
32. Várias estratégias de controlo de concorrência:
Pessimista: lock de registos ou tabela, específico da BD
Optimista:
Versão: numérico, data e hora, ROWVERSION (SQL Server)
Todos/Sujos: todos os campos ou apenas os modificados
Propriedades individuais podem ser configuradas para
entrar no controlo de concorrência
Uma transacção deve ser sempre criada
Um ou mais registos podem ser explicitamente
bloqueados (Lock)
É lançada uma excepção no caso de uma
violação de concorrência
Copyright (c) Ricardo Peres 2010
33. Interceptors recebem
notificações quando
certos eventos ocorrem
Cancelar uma operação
(delete, update, insert) é
possível pelo retorno de
um valor de veto
Apenas um interceptor
por sessão
Listeners recebem
notificações quando
certos eventos ocorreram
ou vão ocorrer
Apenas é possível
cancelar lançando uma
excepção
O NHibernate Validator
depende de listeners
Interceptors (IInterceptor) e listeners (IxxxListener) podem ser
aplicados ao nível da session factory ou da sessão
Outra opção consiste em implementar as interfaces IValidator e
ILifecycle
Um listener pode ser registado em código ou no ficheiro .config
37. É possível definir carregadores para
tipos personalizaos (tipos simples,
IUserType, tipos compostos,
ICompositeUserType), com os quais o
NHibernate não sabe lidar (imagens, por
exemplo)
Em tipos compostos até é possível fazer
queries pelas propriedades declaradas
nos tipos personalizados
Copyright (c) Ricardo Peres 2010
39. Associada à sessão
As sessões stateless não usam CPN
Pode ser desactivado em sessões
normais
As entidades carregadas são colocadas
na CPN, e posteriormente são sempre daí
obtidas (excepto quando forem
refrescadas)
Uma implementação do pattern Identity
Map
Copyright (c) Ricardo Peres 2010
40. Associada à session factory
Activada entidade a entidade
Aplica-se tanto a entidades como a queries
Vários fornecedores disponíveis (NHContrib):
Fornecedor Descrição
SysCache Uses System.Web.Caching.Cache as the cache provider
SysCache 2 Similar to NHibernate.Caches.SysCache, uses ASP.NET cache plus SQL
dependencies
Prevalence uses Bamboo.Prevalence as the cache provider, a .NET implementation
of the object prevalence concept brought to life by Klaus Wuestefeld
in Prevayler
MemCache Uses memcached, a high-performance, distributed memory object
caching system, generic in nature, but intended for use in speeding up
dynamic web applications by alleviating database load. Basically a
distributed hash table
Velocity Uses Microsoft Velocity which is a highly scalable in-memory
application cache for all kinds of data
SharedCache High-performance, distributed and replicated memory object caching
system
41. Projecto Descrição
NHibernate Attributes (NHContrib) Mapeamento por atributos
NHibernate Search (NHContrib) Integração com Lucene.NET
NHibernate Validator (NHContrib) Validação de estado
NHibernate Burrow (NHContrib) Conversações e persistência entre pedidos
em aplicações web
NHibernate Caches (NHContrib) Fornecedores de cache de 2º nível
NHibernate Proxy Generators (NHContrib) Pré-geração de classes proxy
NHibernate Spatial (NHContrib) Suporte para tipos de dados geo-
referenciados (SQL Server, PostgreSQL)
NHibernate Shards (NHContrib) Particionamento horizontal de BDs
NHibernate User Types (NHContrib) Tipos de dados específicos do Oracle e SQL
Server
NHibernate Tasks (HBM to .NET, HBM to
DDL) (NHContrib)
Geração de classes .NET a partir dos
mapeamentos HBM.XML
42. Microsoft
Microsoft LINQ to SQL
Gratuito
POCOs
Apenas SQL Server
Physical mapping to tables, not a conceptual
model
Apenas BD primeiro
Apenas suporta a estratégia table per class
hierarchy
Microsoft Entity Framework
Gratuito
Por agora, apenas SQL Server, Oracle e MySQL
são possíveis
POCOs e não POCOs
Modelo conceptual
Código primeiro ou BD primeiro
Todas as estratégias de mapeamento de
heranças são suportadas
Non-Microsoft
Castle ActiveRecord
Open Source
Baseado no NHibernate
Faz algumas assumpções sobre o modelo
Não POCOs
Todas as estratégias de mapeamento de
heranças são suportadas
SubSonic
Gratuito
POCOs e não POCOs
SQL Server, Oracle, MySQL, PostgreSQL, Vista
DB, SQL Server CE e SQL Lite
Apenas BD primeiro
Apenas suporta a estratégia table per class
hierarchy
LLBLGen Pro
Comercial
Múltiplas BDs suportadas
Não POCOs
Apenas BD primeiro
Apenas suporta a estratégia table per class
hierarchy
43. Uma framework O/RM matura
Altamente extensível
Vasta comunidade de utilizadores
Projectos relacionados muito interessantes
Capaz de ombrear com outros produtos
O/RM estabelecidos
Copyright (c) Ricardo Peres 2010
44. Ayende @ Rahien
Bamboo.Prevalence
Catalog of Patterns of Enterprise Application Architecture
First and Second Level Caching in NHibernate
Fluent NHibernate
NHibernate Forge
HunabKu
Memcached
NHibernate Contrib
NHibernate Mapping - Inheritance
NHibernate Users Mailing List
uNhAddins
Using NHibernate With Stored Procedures
Velocity (AppServer Fabric Caching)
Copyright (c) Ricardo Peres 2010
47. A sua opinião é
importante!
Complete o questionário
de avaliação e devolva-o
à saida.
A sua opinião é
importante!
Complete o questionário
de avaliação e devolva-o
à saida.
Copyright (c) Ricardo Peres 2010