Introduction à NHibernate :
Venu du monde JAVA (hibernate), nHibernate est un ORM, en fait un boite à outils qui facilite le développement connecté à des bases de données, en automatisant une grand part du travail et en ce basant sur des modèles objets et un découplage fort.
NHibernate est une alternative à la solution de Microsoft avec son EntitiesFrameWork.
Si vous lisez le code de nHibernate, vous découvrirez un code sublime, complet flirtant avec la perfection.
L'avantage d'un tel outil c'est que cela simplifie grandement le travail des développeurs.
Le désavantage est qu'en cas de bug dans NHibernate il faut être un véritable gourou pour s'en sortir.
Toutefois mon approche dans les tutorials que je vais vous proposer est surtout de promouvoir une approche robuste et old-school.
Prérequis :
Le plus simple est d'aller dans la section téléchargement et de télécharger la collection de DLLs nécessaire.
Il vous faut aussi une base de données (dans notre cas Microsoft SQL Express) et Visual Studio (2008/2010/Express) ou SharpDevelop.
Premier exercice
Dans ce premier exercice nous allons faire mumuse avec qu'une seule table.
Etape n°1 : Créons un projet nhibernate FirstApplication (application console) et ajoutons nos dlls.
Créez un projet .net c# console. Puis ajoutez dans vos références les DLLS contenus dans le zip précédemment télécharger. Je vous conseille de vous créer un répertoire unique contenant votre collection de DLLS (c:\tuto\shareddlls par exemple).
Dans vos références vous devez avoir cela maintenant :

Etape n°2 : Créons notre modèle de donnée
Dans ce premier tuto nous allons juste créer une table Person qui contient le prénom et le nom de personne.
Ouvrez le fichier program.cs.... Puis créez la classe suivante.
public class Person
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
Vous pouvez faire un premier build.
La force justement des ORM et de NHibernate est que tout repose sur des objects...Ce qui facilite grandement l'accès aux données d'autant qu'elles sont toujours typées.
Etape n°3 : Créons un mapping.
Il existe plusieurs manières de créer un mapping avec NHibernate, y compris en utilisant des fichier <nomdumapping>.hbm.xml... Mais là je vous propose d'utiliser un POCO, une classe. Créez donc le fichier mapping.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Mapping;
namespace FirstApplication
{
public class PersonMap : ClassMap<Person>
{
public PersonMap()
{
Id(x => x.Id);
Map(x => x.FirstName);
Map(x => x.LastName);
Table("Person");
}
}
}
Vous pouvez refaire un build. Vous remarquez quand dans PersonMap(), notre constructeur, nous définissons les champs de notre table (FirstName, LastName), mais aussi l'ID (toutes les tables doivent avoir un ID) et le nom de la table.
Etape n°4 : Créons notre base de données.
Via le Server Explorer de Visual Studio ou depuis un autre EDI créer une base de données vide dans SQL (Dans notre cas MS SQL Express).
Vous devez avoir ceci après dans le server Explorer.

Etape n°5 : Créons notre configuration à la base de données.
Nous devons maintenant renseigner NHibernate quand à la base de données à utiliser. Pour cela nous créons un fichier de configuration config.cs qui doit avoir ce contenu.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Tool.hbm2ddl;
namespace FirstApplication
{
public class NhibernateHelper
{
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory
{
get
{
if (_sessionFactory == null)
{
InitializeSessionFactory();
}
return _sessionFactory;
}
}
private static void InitializeSessionFactory()
{
_sessionFactory = Fluently.Configure()
.Database(MsSqlConfiguration.MsSql2008
.ConnectionString(@"Data Source=jerome-pc\sqlexpress;Initial Catalog=mydatabase;Integrated Security=True;Pooling=False")
.ShowSql())
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Person>())
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
.BuildSessionFactory();
}
public static ISession OpenSession()
{
return SessionFactory.OpenSession();
}
}
}
Vous pouvez refaire un Build.
Dans ce cas nous utilisons une SessionFactory qui gérera la persistence de notre notre connexion en utilisant un Singleton pour la gérer.
Etape n°6 : Créons et lisons un record
C'est le plus de NHibernate, en quelques lignes nous allons créer et lire une donnée dans notre table Person. Si vous doutez encore de la pertinence de cet outil, je vous invite à juste essayer de faire pareil avec ADO.net...
Pour créer un record il suffit de :
using (var session = NhibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var person = new Person
{
FirstName = "Dimitri" , LastName = "Fortias"
};
session.Save(person);
transaction.Commit();
Console.WriteLine("OK");
}
}
Faites un build exécutez le code et allez voir le contenu de votre table (qui a été automatiquement créée). Vous devez avoir ceci.
Vous remarquez qu'un avantage de NHIBERNATE est d'être transactionnel ce qui est un plus pour gérer les accès concurrentiels et il gére la persistence au niveau de la session avec à la méthode SAVE.

Pour lire la donnée il suffit de
using (var session = NhibernateHelper.OpenSession())
{
Console.WriteLine("lisons la DB maintenant");
var personQuery = (from Person in session.Query<Person>()
where Person.Id == 1 select Person).Single();
Console.WriteLine("Name : {0}, {1}", personQuery.FirstName, personQuery.LastName);
}
Vous remarquez qu'on utilise LINQ pour faire ses queries dans la base de données.
Si on combine les deux codes vous avez :
using System.Linq;
using System.Text;
using NHibernate.Linq;
namespace FirstApplication
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("nous allons créer une personne");
using (var session = NhibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var person = new Person
{
FirstName = "Dimitri" , LastName = "Fortias"
};
session.Save(person);
transaction.Commit();
Console.WriteLine("OK");
}
Console.WriteLine("lisons la DB maintenant");
var personQuery = (from Person in session.Query<Person>()
where Person.Id == 1
select Person).Single();
Console.WriteLine("Name : {0}, {1}", personQuery.FirstName, personQuery.LastName);
}
}
}
Vous devez avoir ce résultat...

Voila de quoi vous amusez et apprendre le b;a;BA de NHIBERNATE.
Si vous jouez assez vous aller découvrir qu'à chaque redémarrage de l'application, au moment de l'initialisation dans config.cs la table dans la base de donnée est totalement vidée. Dans la suite de ce tutorial, nous allons régler cela et ajouter des méthodes supplémentaires.
Second exercice
Le plus simple est de sauvegarder le premier exercice et de l'étendre avec de nouvelles méthodes.
Etape n°1 : Modifions le config.cs
Recherchez dans config.cs la ligne suivante
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true, true))
Puis changez la en
.ExposeConfiguration(cfg => new SchemaExport(cfg).Create(true,false))
En réalisant cela, l'export de la DB vers le modèle objet est possible.
Etape n°2 : Lisons le contenu de la table avec NHibernate
using (var session = NhibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
var Persons = session.CreateCriteria(typeof(Person)).List<Person>();
transaction.Commit();
Console.WriteLine("nb of record {0}.", Persons.Count);
}
}
Dans ce cason lit l'ensemble de la table.... Mais on peut aussi appliquer une query SQL (remplacer le code dans le second using)...
IList<Person> Persons = new List<Person>();
IQuery query = session.CreateQuery("From Person");
Persons = query.List<Person>();
transaction.Commit();
Console.WriteLine("Nb or record = {0}.", Persons.Count);
Etape n°3 : Ecrivons la méthode Create.
private static void Create(Person thisPerson)
{
using (var session = NhibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Save(thisPerson);
transaction.Commit();
}
session.Close();
}
}
Etape n°4 : Ecrivons la méthode Update.
private static void Update(Person thisPerson)
{
using (var session = NhibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Update(thisPerson);
transaction.Commit();
}
session.Close();
}
}
Etape n°5 : Ecrivons la méthode Read.
private static Person Read(int thisID)
{
using (var session = NhibernateHelper.OpenSession())
{
var personQuery = (from Person in session.Query<Person>()
where Person.Id == thisID
select Person).Single();
return personQuery;
}
}
Etape n°6 : Ecrivons la méthode Delete.
private static void Delete(Person existingPerson)
{
using (var session = NhibernateHelper.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
session.Delete(existingPerson);
transaction.Commit();
}
}
}
Etape n°7 : Ecrivons la méthode DiplayAllPersons.
private static void DisplayAllPersons()
{
using (var session = NhibernateHelper.OpenSession())
{
using (ITransaction transaction = session.BeginTransaction())
{
var Persons = session.CreateCriteria(typeof(Person)).List<Person>();
transaction.Commit();
Console.WriteLine("nb of record {0}.", Persons.Count);
foreach (Person myPerson in Persons)
{
Console.WriteLine("ID:{0}.Nom:{1}.Prenom:{2}."
, myPerson.Id
, myPerson.FirstName
, myPerson.LastName);
}
}
}
}
Etape n°8 : Jouons maintenant.
Maintenant que tout est Ok je vous propose de modifier le Main en y tapant ce code ci
Console.WriteLine("Jouons avec NHibernate !");
Console.WriteLine("---------------------------------------------------------------------------");
Console.WriteLine("Créons plusieurs personnes (les objets)");
var person1 = new Person
{
FirstName = "Jerome",
LastName = "Fortias"
};
var person2 = new Person
{
FirstName = "Bill",
LastName = "Gates"
};
var person3 = new Person
{
FirstName = "inspecteur",
LastName = "Colombo"
};
DisplayAllPersons();
Console.WriteLine("Ajoutons les personnes dans la Table de la DB");
Create(person1);
Create(person2);
Create(person3);
DisplayAllPersons();
Console.WriteLine("Modifions le person1");
person1.LastName = "NOM";
Update(person1);
DisplayAllPersons();
Console.WriteLine("Selection la personne avec l'ID = 1 et effaçons la");
var selectedPerson = Read(1);
Delete(selectedPerson);
DisplayAllPersons();
Console.WriteLine("fin");
Vous devez avoir ce résultat ci


conclusion
Si vous refaites la meme application en se basant sur ADO.net vous mettrez certainement beaucoup plus de temps ( 3 à 4 fois plus au bas mot).
L'avantage de NHibernate est avant tout là, la vitesse, et la maintenabilité du code, mais cela a un prix la performance et aussi la nécessité d'etre un gourou pour débugguer NHibernate. Reste que NHibernate vous fournit automatiquement l'essentiel depuis la gestion du cache jusqu'aux accès concurrentiels. C'est donc un outil à connaitre...(même si cela vient du monde Java et na).
Jérôme Fortias

Téléchargements :
Liens internet :

