Ladda ner presentationen
Presentation laddar. Vänta.
1
NHibernate i praktiken Vittnesbörd från en användare
2
Min bakgrund Objektorientering (OO) sedan 1985 SQL sedan 1990 50 % från Domain Model (DM), 50 % från databas (DB) Gör DB-schemat för hand Har skrivit egen Object/Relational-mapper (O/R- mapper) –För Delphi, 1995
3
Användare Ej dykt i NH-koden –Skönt att bara använda ibland Inte speciellt avancerad POCO (Plain Old CLR Object) Vill prata om helheten i ett POCO och TDD scenario
4
O/R-mappning i ett nötskal Objekts fält –Ta (utvalda) fält och lagra i kolumner på en rad i en tabell Objekts relationer –en-till-en –en-till-många –många-till-många –arv (inte idag)
5
Objekt- kontra databasidentitet Ett objekts identitet är dess ”adress” En rad i en databas identifieras med en PK I ett programs adressrymd så vill vi bara att ett objekt laddat från databasen ska förekomma en gång –Ok, adressrymd inom ett visst scope
6
NHibernate Session Databaskoppling Identity Map (kopplar samman identitet i minne och i databas) –En rad laddad bara en gång –Jämför på objekt istf fält –http://martinfowler.com/eaaCatalog/identityMap.htmlhttp://martinfowler.com/eaaCatalog/identityMap.html Unit of Work (vad ska göras mot databasen) –Vad ska göras mot databasen vid Flush –http://martinfowler.com/eaaCatalog/unitOfWork.htmlhttp://martinfowler.com/eaaCatalog/unitOfWork.html Webbapplikation i lastbalancerad farm –http://www.ingolundberg.com/Weblog.aspx?item=NHibernate- Session-handling-in-a-Web.htmhttp://www.ingolundberg.com/Weblog.aspx?item=NHibernate- Session-handling-in-a-Web.htm
7
Domain Model Driver utveckling från DM –Test Driven Development (TDD) I största möjliga mån ovetande om lagring –Pragmatisk (Id + mappningsfil) –Abstraktion av lager eller tjänst
8
Exempel BookCopy ~= exemplar
9
Exempel Kort demo av app
10
Exempel
11
Persistence Data Access Objects (DAO) –BookDAO –BorrowerDAO –etc
12
WebGuiMdl
13
WebGuiMdlGlue [Serializable] public class BookListingMdl_Collab: BookListingMdl.Collab { public BookListingMdl_Collab(NHibernate.ISession s) { _s = s; } public IList GetBooks() { return new BookDAO(_s).FindAll(); } public int GetItemNumber() { return new ItemNumberHandlerDb().GetNumber(); } public IList GetAllAuthors() { return new AuthorDAO(_s).FindAll(); } public void MakePersistent(Book book) { new BookDAO(_s).MakePersistent(book); } public void MakeTransient(Book book) { new BookDAO(_s).MakeTransient(book); } public void PersistAll() { NHibUtil.PersistAll(_s); } NHibernate.ISession _s; }
14
Web app
15
Pekare BookCopy Borrower –many-to-one mappning Samtidigt one-to-many åt andra hållet –Man kan skippa den ena eller andra sidan av relationen
16
Medlemsset Inga direkta publika set på klassen På klassen –ICollection –AddFoo –RemoveFoo –HasFoo –o dyl På Book public BookCopy AddBookCopy(int itemNumber) { BookCopy res = new BookCopy(this, itemNumber); _copies.Add(res); return res; } public ICollection BookCopies { get { return _copies; } Iesi.Collections.ISet _copies;
17
En till många Book BookCopy –Composite aggregate –Book har livstidskontroll av BookCopy
18
Ta bort en bok Om boken har en kopia utlånad så vill vi förhindra borttaget. –En bok sopar alla sina kopior utan att upptäcka om en kopia är utlånad (BookCopy- rad pekar på låntagare) –Fixar vi med kod –Samtidighetsproblem fixar vi med koll i databasen visas lite senare
19
Test mot databasen LendLibNUnit db för tester –LendLib db för appen SetUp –sproc NUnitSetup –Minimalt utgångsmaterial TearDown –sproc NUnitTeardown
20
Ta bort en bok [Test] public void DeleteBookWithBookCopyOut() { Borrower borrower = new BorrowerDAO(Session).FindByBorrowerId(1); Book b = dao.FindById(idBookBar); BorrowFirstCopy(b, borrower); // does not flush try { dao.MakeTransient(b); A.Fail("Should fail"); } catch(BookNotOkToDeleteException) {} } BookDAO public void MakeTransient(Book book) { if (!book.IsOkToDelete()) throw new BookNotOkToDeleteException(); base.MakeTransient(book); }
21
Många till många Author har skrivit många böcker –Vill du att en Author ska kunna tas bort om han ”står som författare” till någon bok? –Vill du att en Bok ska kunna tas bort som har författare? Kolla in vilken sida som du sätter inverse=true på –Bilden säger inverse=true på Book sidan Kombination av DM och db Skriv tester
22
Lazy Load Member-set Relationer och laddning av data Laddar när man petar på den –Se touch på.Count i test några bilder bort
23
Samtidighet Optimistisk med sen kontroll via versionsräknare Glöm inte bort databasens förmåga att upprätthålla constraints Simulerar samtidighet i test genom att använda två NH-sessioner
24
version [Test] public void DeleteBookWhenSomeoneAddsNewCopyBetweenReadAndDelete() { // User 1 Book b = dao.FindById(idBookBar); int c = b.BookCopies.Count; // touch lazy loaded collection using (NHibernate.ISession s = NHibUtil.CreateSession()) { // User 2 (in another session) Book b2 = new BookDAO(s).FindById(idBookBar); b2.AddBookCopy(1212); short oldCC = b2.CC; NHibUtil.PersistAll(s); A.AreEqual(oldCC+1, b2.CC); // this is actually enough to test... } // User 1 continues dao.MakeTransient(b); try { NHibUtil.PersistAll(Session); A.Fail("Should fail"); } catch(ChangedOrDeletedByOtherUserException) // StaleObjectStateException {} }
25
Ta bort en bok – lurigt fall [Test] public void DeleteBookWithBookCopyOutMultiUserSituationCaughtByDbFallback() { // User 1 Book b = dao.FindById(idBookBar); int c = b.BookCopies.Count; // touch lazy loaded collection using (NHibernate.ISession s = NHibUtil.CreateSession()) { // User 2 (in another session) Borrower borrower = new BorrowerDAO(s).FindByBorrowerId(1); Book b2 = new BookDAO(s).FindById(idBookBar); BorrowFirstCopy(b2, borrower); NHibUtil.PersistAll(s); } // User 1 continues dao.MakeTransient(b); try { NHibUtil.PersistAll(Session); A.Fail("Should fail"); } catch(NHibernate.ADOException ex) { // expecting the fallback to step in; a trigger checking delete of BookCopy if (ex.InnerException == null || ex.InnerException.Message != "Some bookcopy is not in library") throw; }
26
Ta bort en bok – lurigt fall create trigger BookCopyInLibraryCheck on BookCopy for delete as if exists(select * from deleted where refBorrower is not null) begin raiserror ('Some bookcopy is not in library', 11, 1) end
27
SQL-action Använd t.ex. SQL Server Profiler Skriv gärna utforskande NUnit-tester
28
Kan man glömma rdb:n med O/R? Jag tycker inte det –Jag har aldrig försökt –Kan inte gärna bortse från det jag råkar veta om rdb Man slipper skriva en massa kod som är i stort sett samma varje gång
29
Bara solsken? Inte riktigt nöjd med kasta session vid exception
30
Referenser och länkar http://www.nhibernate.org/ –Gemensamt med Hibernate The Server Side www.theserverside.netwww.theserverside.net –http://www.theserverside.net/articles/showarticle.tss?i d=NHibernatehttp://www.theserverside.net/articles/showarticle.tss?i d=NHibernate –http://www.theserverside.net/articles/showarticle.tss?i d=NHibernateP2http://www.theserverside.net/articles/showarticle.tss?i d=NHibernateP2 –Se upp med try-catch-hanteringen Boken Hibernate in Action av Bauer & King –Java
31
Ingo www.ingolundberg.com –http://www.ingolundberg.com/download/Lend Lib-dist-2006-03-31.ziphttp://www.ingolundberg.com/download/Lend Lib-dist-2006-03-31.zip www.knowit.se www.dev112.com
Liknande presentationer
© 2024 SlidePlayer.se Inc.
All rights reserved.