
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
Naše projekty
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
- NHibernate for .NET - oficíální stránky
- NHibernate forge - komunitní stránky
- nhusers - skupina na Google groups
- Summer of NHibernate - série screencastů o NH
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.




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
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..
Není jednodušší použít LINQ?
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.
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://sourceforge.net/…howfiles.php?…
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.
Určitě by zájem o pokračování byl… ;)
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.codeproject.com/…actices.aspx
Mimochodem, mrkněte na http://nhprof.com – zajímavá věcička ;-)
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
Ted jsem se setkal v Jave s Hibernate a usetrilo nam to hoooodne prace!
Napsat komentář
Upozornění: komentáře jsou schvalovány!