NHibernate

Představení známého ORM pro .NET


Petr Stříbný

Autorem článku je Petr Stříbný. Programátor. Věnuje se internetovým stránkám, technologiím, jazykům C# a PHP. Při přípravě na maturitu sepsal některé maturitní otázky na web. Kromě toho si píše osobní blog.

Zařazení článku

ASP.NET Databáze Programování SQL

Naše projekty

Angličtina AGJ.cz
Dějepis


NHibernate je open source ORM nástroj pro .NET licensovaný pod GNU Lesser General Public License (port původního Hibernate napsaného v Javě). Projekt je vyspělý a široce používaný, o čemž se můžeme přesvědčit díky existenci několika projektů, které práci s NHibernate značně zjednodušují (ať už se jedná o Burrow, Fluent NHibernate nebo třeba NH Prof) nebo díky značně velké komunitě, která často nahrazuje (bohužel) zastaralou či neúplnou oficiální dokumentaci.   

Čím se NHibernate liší?

Některé ORM nástroje fungují jako generátory bázových/parciálních tříd (nebo dodávají "obecné" bázové třídy), ze kterých je poté nutné vycházet. Tato cesta nás pak nutí přizpůsobovat datový model kontrétnímu ORM a svazuje nám tak ruce. Naproti tomu NHibernate nevyžaduje prakticky žádné změny jak v našem objektovém modelu, tak v databázi. Umožňuje nám to např. použít stávající databázové schéma, implementovat Repository pattern (který vede k jednoduššímu testování) a další věci.

Konfigurace - XML kam se podíváš

Všechny výše zmíněné pěkné věci musí být samozřejmě něčím vykoupeny. NHibernate ještě není ve fázi, že by uměl věštit z křišťálové koule a proto je nutné vazby mezi aplikačním a databázovým datovým modelem popsat ručně. A jak tomu ve světě .NET/Javy bývá - v XML. Psaní těchto mapovacích pravidel může být zdlouhavé (opravdu - zkoušel jsem to!) a může také vést k těžce odhalitelným chybám. Nicméně je několik způsobů, jak si toto psaní ulehčit a jak se pomocí testování přesvědčit, že všechno funguje jak má.

První možností je použití různých generátorů (většinou ve směru databáze -> mapovací soubory) . Ty skutečně můžou urychlit celý proces vývoje, ale nejen, že nemusí vygenerovat všechno podle našich představ, ale pořád neřeší možné budoucí změny. Proto mnohem lepším způsobem jak se mapovacím XML souborům vyhnout je projekt Fluent NHibernate, který nám umožní psát mapování přímo v jazyce C# (popř. jiném) a zkontrolovat tak jeho správnost již v době překladu.

Pokud však chcete mít jistotu, že máte mapování opravdu 100% správně, přijdou na řadu integrační testy. V odhalování chyb typu záměna vlastnosti on-delete opravdu neocenitelné!

Pro představu vám ještě ukážu, jak takový konfigurační soubor může vypadat. Tento konkrétní mapuje třídu Role:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"  assembly="Project.DataAccess" namespace="Project.Models">
  <class name="Role" table="Roles">

    <id name="Id" access="nosetter.camelcase-underscore" unsaved-value="0">
      <generator class="native" />
    </id>

    <property name="Name" not-null="true" type="String" length="100" />

    <bag name="Users" table="Roles_Users" inverse="true" generic="true" cascade="save-update" lazy="true">
      <key column="RoleId" />
      <many-to-many column="UserId" class="User" />
    </bag>
  </class>
</hibernate-mapping>

Správa sezení

Správa session - NHibernate se stará o komunikaci s databází prostřednictvím sezení (session). Změny provedené v rámci sezení nejsou ihned prováděny, ale čeká se, až změny potvrdíme ručně. Samotný koncept sezení má své výhody i nevýhody - jednou z nevýhod je např. režie spojená se SessionFactory. Podívejme se na jednoduché načtení a aktualizaci objektu:

var config = new Configuration();
config.AddAssembly("NaseAssemblySMappingSoubory");
var factory = config.BuildSessionFactory();

using (ISession session = factory.OpenSession())
{
	User u = session.Get(1);
	u.Name = "novejmeno";
	
	session.Update(u);
	session.Flush();
}

factory.Close();

Ten hlavní problém však přichází u ASP.NET aplikací. Kam vytváření SessionFactory dát? Jak mít otevřené sezení přes celý a právě jeden HTTP požadavek s voláním Flush() na konci? Naštěstí existuje projekt NHibernate Burrow, který právě tyto problémy řeší. Opravdu doporučuju nastudovat, ušetří vám několik bezesných nocí!

Další vlastnosti

Lazy loading je v NHibernate plně podporován a možnosti jeho nastavení jsou naprosto flexibilní.

NHibernate je nezávislý na databázovém systému.

Možnosti dotazování zahrnují SQL, HQL (což je takové SQL - akorát nad objekty) a NHibernate Criteria API, které sice nevypadá zrovna nejlépe, ale svoji práci splní. Další možností bude využití jazyka LINQ. NHibernate Linq - projekt implementace jazyka LINQ pro NHibernate umožní dotazování nad daty podobně jako u LINQ To SQL nebo LINQ To Entities. Momentálně ve fázi alfa a bez dokumentace - tak či tak se jedná o přelomový projekt, který posune NHibernate zase o kus dál. Následuje ukázka Criteria API:

IList cats = sess.CreateCriteria(typeof(Cat))
    .Add( Expression.Like("Name", "Fritz%") )
    .Add( Expression.Between("Weight", minWeight, maxWeight) )
    .List();

NH prof

NH prof je profiler pro NHibernate, jehož autor je přímo jedním z programátorů samotného NHibernate. I když se jedná o placený a ne zrovna levný nástroj - poodhalí vám celou tu magii, kterou za vás NHibernate dělá.

Castle ActiveRecord

Pokud nechcete používat "čistý" NHibernate, chcete se vyhnout mapování v XML, správě sezení a nevadí vám ActiveRecord pattern - zkuste Castle ActiveRecord, který je nad NHibernate vybudován.

Knihy

Jedinná kniha o NHibernate je NHibernate in Action, která ač nedávno vydaná, je psaná pro předchozí major verzi. Přesto však může dobře posloužit.

Internetové zdroje

Na závěr bych se rád omluvil za všechny chyby a nepřesnosti a za újmu na zdraví, kterou vám článek mohl způsobit. Nejsem NHibernate guru, takže budu rád když mě doplníte/opravíte. Ještě zvažuju článek o tom, jak s NHibernate prakticky začít, tak pokud o něj máte zájem, napište!

Článek publikován 2009-02-06 01:42:21.


Linkovat Přidat odkaz na del.icio.us

Komentáře

Jen doplnění k Castle ActiveRecord. Ten velice zjednodušuje jak samotné mapování, tak správu session ve zmiňovaném ASP.NET, kde stačí zaregistrovat pouze jeden HttpModul a máme per request session. Navíc není nutné používar bázovou třídu a tudíž active record pattern, ale mít POCO a repository pattern. Více jsem napsal u sebe článku Persistence modelu pomocí ActiveRecord

Aleš Roubíček

Ještě jsem v článku zapomněl zmínit NHibernate Validator – validační engine pro NH. Sice různých validačních frameworků existuje pro .NET celá řada, ale není důvod ho neznímit..

Petr Stříbný

Není jednodušší použít LINQ?

Kostkáč

Kostkáč: asi myslíš LINQ To SQL – ano – je jednodušší ho použít. Jenže LINQ To SQL má několik omezení – např. podporuje pouze MS SQL Server.

Petr Stříbný

Existuje linq provider aj pre nhibernate. Pouzivam zatial betu pre verziu 2.1 a som plne spokojny ale nedavno vysla alfa pre verziu 2.0: http://source­forge.net/…how­files.php?…

vlko

No akurat pozeram, ze pouzivam prave tu alfa verziu pre 2.0.1:) Takze beriem poznamku spat. Kazdopadne do NHibernate 2.1 by podla zdrojakov na nhforge mal byt linq provider rozdielny, ktory pravdepodobne bude generovat priamo hql(sql??) a tym padom by mal byt teoreticky rychlejsi, no uvidime, 3 mesiace v zdrojakoch nebola urobena ziadna zmena, tak sa nechajme prekvapit.

vlko

Určitě by zájem o pokračování byl… ;)

baCZa

jj přesně tak, super článek. Jak řešíte správu session v ASP.NET aplikaci ? Já prozatím přes HttpContext.Current ale nevím, jestli je to nejvhodnější.

Také jsem nalezl řešené přes HttpModul viz.: http://www.co­deproject.com/…ac­tices.aspx

Mimochodem, mrkněte na http://nhprof.com – zajímavá věcička ;-)

strook

strook: Ano přes HttpModul. Dříve jsem měl napsaný vlastní, teď používám právě v článku zmíněný Burrow. Tady je asi nejrychlejší návod, jak ho nasadit: http://nhforge­.org/…started­.aspx

Petr Stříbný

Ted jsem se setkal v Jave s Hibernate a usetrilo nam to hoooodne prace!

Petr Lev

Napsat komentář

Upozornění: komentáře jsou schvalovány!




Napište prosím, kolik je 10 bez pěti:


Náhled

Nepřehlédněte

© 2005—2007 Zápisník programátorů. Veškerá práva vyhrazena.
O zápisníku — Autoři — Archív