Mazur (m-a-t-i@o2.pl) 22 października 2008 Akademia Górniczo-Hutnicza, Automatyka i Robotyka
Plan Wyjaśnienie tematyki Przykład wprowadzający Wyjaśnienie pojęć wydajnościowe, funkcjonalne Praktyczne przedstawienie podstaw korzystania z obu technologii
Przykład - relacyjna baza danych id imie nazwisko 1 Zenon Śmigły 2 Gustaw Kowalski Tabela: Znajomi id osoby numer 1 500500500 1 128877654 Tabela: Telefony id osoby ulica miasto 1 ul. Sezamkowa Kraków 2 ul. Smutna Katowice Tabela: Adresy
Przykład - język obiektowy Telefon +telefon: string Znajomy +imie: string +nazwisko: string +telefony: List<Telefon> +adresy: List<Adres> Adres +ulica: string +miasto: string
Problem Jak wymieniać dane pomiędzy bazą a językiem obiektowym?
Definicja... Mapowanie obiektowo-relacyjne (ang. Object-Relational Mapping, ORM, O/RM, O/R mapping) jest to technika programowania polegająca na konwertowaniu danych pomiędzy relacyjną bazą danych a zorientowanymi obiektowo językami programowania. Podejście to tworzy wirtualną bazę obiektową, która może być wykorzystywana wewnątrz języka programowania. Zarządzanie danymi w językach obiektowych jest zwykle zaimplementowane poprzez manipulacje obiektami, które rzadko są skalarami.
Wady i zalety ów Zalety operujemy tylko na obiektach uproszczenie kodu Wady spadek wydajności tracimy wpływ na generowny SQL
LINQ Language-INtegrated Query Integralna część frameworka.net w wersji 3.5 LINQ w standarwej implementacji działa na danych XML oraz SQL.
Port Hibernate Core na platformę.net (Hibernate to biblioteka dla jezyka JAVA) Zewnętrzna biblioteka Działa tylko na bazach danych.
Wydajność Scenariusze testowe: 1 Pobranie 10 rekordów. Zostają one posortowanie i stronicowane. W tablicy znajduje się 100 rekordów. Operacja powtarzana 100 razy. 2 Identyczny ze secenariuszem 1, ale w tablicy jest 10000 rekordów. 3 Dodanie rekordu i usunięcie go. W tablicy jest 100 rekordów. 4 Identyczny ze scenariuszem 3, ale w tablicy jest 10000 rekordów. Na podstawie testu Maximiliana Bellera
Wydajność - wyniki Odczyt, 100 rekordów w bazie: 2,5 Odczyt, 10000 rekordów w bazie: 2 250 1,5 1 0,5 Linq ADO.net 200 150 100 Linq ADO.net 0 Technologia 50 0 Technologia
Wydajność - wyniki Zapis, 100 rekordów w bazie: 3,5 3 2,5 Zapis, 10000 rekordów w bazie: 3,5 3 2,5 2 1,5 Linq ADO.net 2 1,5 Linq ADO.net 1 1 0,5 0 Technologia 0,5 0 Technologia
Wydajność - podsumowanie Zapis jest o 31% wolniejszy od ADO LINQ jest wolniejsze o 42% od ADO Odczyt jest o 25% wolniejszy niż Linq Linq jest o 19% wolniejsze od ADO.NET
Linq - zalety i wady Za Linq jest częścią platformy.net 3.5 Zintegrowane z Visual Studio Możliwość sprawdzania błędów w czasie kompilacji Możliwość rozszerzania klas wygenerowanych przez LINQ Przeciw Zupełna nowość Automatyczna generacja klas - ograniczona kontrola
- zalety i wady Za Dojrzały produkt z dużą społecznością w świecie.net i javy Łatwy w użyciu Niezależny od bazy danych Przeciw Zewnętrzna biblioteka Brak integracji z Visual Studio
Typy anonimowe (var) musi być od razu zainicjowany nie może być zwracany przez funkcję jedynie lokalne deklarcje (np. wewnątrz metody) zamieniany na typ właściwy na etapie kompilacji zapewnia oszczędność w pisaniu kodu Przykład var nazwisko = Mazur ;
Wyrażenia lambda ułatwiają pisanie anonimowych funkcji można je przekazywać jako argument bardzo użyteczne przy zapytaniach w LINQ Składnia (arg1[, arg2, arg3, arg4]) => wyrażenie
Podstawowa składnia LINQ Select var products name = from p in products select p.productname; Where var products name = from p in products where p.price < 50 select p.productname; OrderBy/OrderByDescending var products = from p in products OrderBy p.productname, p.price select p;
Podstawowa składnia LINQ - C.D. Grupowanie var products name = from p in products group p by p.category into g select new {Category = g.key, ProductCount = g.group.count()};
Warto odwiedzić LINQ 101 Samples (http://msdn.microsoft.com/enus/vcsharp/aa336746.aspx) LinqPad (http://www.linqpad.net/)
Przykład praktyczny W oparciu o przykład z początku prezentacji: id imie nazwisko 1 Zenon Śmigły 2 Gustaw Kowalski Tabela: Znajomi id osoby numer 1 500500500 1 128877654 Tabela: Telefony id osoby ulica miasto 1 ul. Sezamkowa Kraków 2 ul. Smutna Katowice Tabela: Adresy
Wykorzystanie LINQ Najpierw dajemy projetu obiekt LINQ to SQL, a następnie za pomocą graficznego edytora dajemy interesujące nas tabele. Kod ZnajomiDataContext db = new ZnajomiDataContext ( ) ; v a r t e l e f o n y z e n k a = from t e l e f o n i n db. Numeries where t e l e f o n. i d z n a j o m y == ( db. Znajomis. S i n g l e <Znajomi >( i d => i d. i m i e == Zenon ) ). i d s e l e c t t e l e f o n ;
Co musimy zrobić żeby zadziałało? 1 Dodać projektu referencje plików:.dll, log4net.dll, Iesi.Collections.dll. 2 Stworzyć klasy dla każdej z tabel 3 Stworzyć plik konfiguracyjny dla 4 Stworzyć pliki mapowań dla klas
Uwagi... Plik konfiguracyjny (hibernate.cfg.xml) powinien we właściwościach mieć ustawione Copy to output na always copy. Warto również dać sobie plik definiujący składnię, co uprości jego buwę. Pliki mapowań nazywają się tak jak klasy (dla klasy Auto, będzie on miał nazwę Auto.hbm.xml). W ich właściwościach należy ustawić dwa parametry: Build action: Embedded Resource Copy to output: always copy
Trochę o HQL u Podstawowy from Product as p Select select p.productname from Product as p Where from Product as p where p.price < 50 Order by from Product as p where p.price < 50 order by p.productname desc, p.price asc
HQL - C.D. Grupowanie select p.category, count( elements(p.category) ) from Products p group by p.group
Garść odsyłaczy Dokumentacja Quick Start Guide Forum Wszystko na: http://www.hibernate.org/22.html#a26
Przyjrzyjmy się temu samemu przykławi zaimplementowanemu przy pomocy.
Plik konfiguracyjny - hibernate.cfg.xml <? xml v e r s i o n= 1.0 encoding= utf 8?> <h i b e r n a t e c o n f i g u r a t i o n xmlns= u r n : n h i b e r n a t e c o n f i g u r a t i o n 2.2 > <s e s s i o n f a c t o r y> <p r o p e r t y name= c o n n e c t i o n. p r o v i d e r >. C o n n e c t i o n. D r i v e r C o n n e c t i o n P r o v i d e r</ p r o p e r t y> <p r o p e r t y name= d i a l e c t >. D i a l e c t. M s S q l 2 0 0 5 D i a l e c t</ p r o p e r t y> <p r o p e r t y name= c o n n e c t i o n. d r i v e r c l a s s >. D r i v e r. S q l C l i e n t D r i v e r</ p r o p e r t y> <p r o p e r t y name= c o n n e c t i o n. c o n n e c t i o n s t r i n g > Data Source=l o c a l h o s t \SQLEXPRESS ; I n i t i a l C a t a l o g=znajomi ; I n t e g r a t e d S e c u r i t y=true </ p r o p e r t y> <property name= show sql >true</ property> </ s e s s i o n f a c t o r y> </ h i b e r n a t e c o n f i g u r a t i o n>
Mapowanie klas Znajomy.cs c l a s s Znajomy { p u b l i c Int64 Id{ get ; s e t ; } p u b l i c s t r i n g I m i e { g e t ; s e t ; } p u b l i c s t r i n g Nazwisko{ g e t ; s e t ; } } Znajomy.hbm.xml <? xml v e r s i o n= 1.0 encoding= utf 8?> <hibernate mapping xmlns= urn: nhibernate mapping 2.2 assembly= nhibernateexample namespace= nhibernateexample. Domain > <c l a s s name= Znajomy t a b l e= Znajomi l a z y= f a l s e > <id name= Id column= id > <g e n e r a t o r c l a s s= n a t i v e /> </ i d> <property name= Imie column= imie /> <property name= Nazwisko column= nazwisko /> </ c l a s s> </ h i b e r n a t e mapping>
Wykorzystanie var cfg = new C o n f i g u r a t i o n ( ) ; c f g. C o n f i g u r e ( ) ; c f g. AddAssembly ( t y p e o f ( Znajomy ). Assembly ) ; I S e s s i o n F a c t o r y f a c t o r y = c f g. B u i l d S e s s i o n F a c t o r y ( ) ; I S e s s i o n s e s s i o n = f a c t o r y. OpenSession ( ) ; I L i s t<telefon> numery zenka =\ s e s s i o n. CreateQuery ( from Telefon numer where numer. Id znajomego = ( s e l e c t zn. I d from Znajomy zn where zn. I m i e = : i m i e ) ). S e t S t r i n g ( i m i e, Zenon ). L i s t<t e l e f o n>( ) ;
Vs. Linq daje nam większe możliwości, ale kosztem większej straty czasu przy konfiguracji. Linq jest o wiele przyjemniejsze w konfiguracji i korzystaniu. Ponieważ nie ma wyraźniego zwycięzcy testu, przy wyborze należy kierować się własnymi preferencjami.
Dziękuję za uwagę!