1 / 51

Технология ORM и

Технология ORM и. её реализации. Что такое ORM?. ORM (Object-relational mapping) —. технология программирования, которая связывает базы данных с. концепциями объектно-ориентированных языков программирования, создавая «виртуальную объектную базу данных». Что такое ORM?.

Download Presentation

Технология ORM и

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ТехнологияORMи еёреализации

  2. ЧтотакоеORM? ORM(Object-relationalmapping)— технологияпрограммирования,которая связываетбазыданныхс концепциямиобъектно-ориентированных языковпрограммирования,создавая «виртуальнуюобъектнуюбазуданных».

  3. ЧтотакоеORM? ЗадачаORMсостоитвуправлениитрансляцией объектныхтиповвзаписибазданныхиобратно. Основнаяпроблемасостоитвтом,чтообъекты имеютиерархическуюструктуру,абазыданных— реляционную.

  4. Классы Классыопределяютсущность Классымогутсодержатьданныеиметоды Классымогутнаследоватьданныеи интерфейсдругихклассов Вкачестведанныхклассымогут содержатьэкземплярыдругихклассов,в томчислесписки.    

  5. Базыданных ОсновнымэлементомБДявляется таблица Таблицымогутсодержатьтолькопростые типыданных Таблицынемогутсодержатьмассивыи списки Таблицымогутбытьсвязанывнешними ключами    

  6. ЗачемнужныORM? Ручноепреобразованиереляционныхданныхв объектыдостаточнотрудоѐмкийпроцесс, которыйведѐткувеличениючислаошибок. ORMберѐтнасебяоперациипо преобразованиюданныхвобъекты, абстрагируяпрограммистаотзнанияо конкретныхСУБД. Объектысостояниекоторыхможетбыть сохранено,азатемвосстановленоназываются хранимымиилиперсистентными(отангл. «persistent»—постоянный,устойчивый).

  7. МинусыORMрешений Дополнительныйслойабстракцииможет сказатьсянапроизводительности. Решениепростыхзадачможетоказаться слишкомсложным. ORMрешениеможетнебытьдостаточно гибким. Дизайнсистемыможетоказаться зависимымотконкретнойORM- библиотеки.    

  8. NHibernate NHibernate—ORM-решениедля платформыMicrosoft.NET,портированное сJava. Этобесплатнаябиблиотекасоткрытым кодом,распространяетсяподлицензией GNULGPL. Текущаяверсия:3.1.0.

  9. NHibernate NHабстрагируетвашеприложениеотлежащейв основеСУБДидиалектаязыкаSQL. ПоддерживаемыеСУБД: MicrosoftSQLServer Oracle MicrosoftAccess Firebird PostgreSQL DB2UDB MySQL SQLite        

  10. ИспользованиеNHibernate ПроцессиспользованияNHibernateсостоитиз четырѐхэтапов: Определениеконфигурацииподключенияк БД(типСУБД,SQL-диалект,строку подключения). Определениедоменныхклассов,которые будутотображатьсянатаблицыБД. НаписаниеконфигурационныхXMLфайлов, осуществляющихотображение(mapping) реляционнойструктурыбазыданныхна доменныеклассывашегоприложения. ПодключениекБДиманипуляцияданнымив терминахдоменныхклассов.

  11. ИспользованиеNHibernate Управлениепараметрамиподключенияможет осуществлятьсяспомощьюобъекта Configurationследующимиспособами: ВызовамиметодаSetProperty. ОпределениемконфигурационногоXMLфайлас именемвида*.cfg.xmlизагрузкойегометодом Configure. МетодConfigureможетбытьвызванбез параметра,чтоуказываетнанеобходимость загрузкиконфигурационногофайласименем hibernate.cfg.xml  

  12. ИспользованиеNHibernate Configurationconfiguration=newConfiguration(); configuration.Configure();

  13. ИспользованиеNHibernate КонфигурационныеXMLфайлы, осуществляющиеотображение, должныиметьимявида*.hbm.xmlи подключатьсякпроектувкачестве EmbeddedResource. Загрузкаmapping-файлов осуществляетсявызовомметода AddAssemblyклассаConfiguration: Configurationconfiguration= newConfiguration(); configuration.Configure(); configuration.AddAssembly("NHibernateDemo");

  14. NHibernate.Пример. Рассмотримпростойпример. Схемабазыданныхимеетследующийвид:

  15. NHibernate.Пример. Самыйпростойкласснашегодоменаимеетследующийвид: namespaceBooks.Domain { publicclassLanguage { publicvirtualintId {get;set;} publicvirtualstringName {get;set;} } } Отметим,чтосвойствакласса,которыеотображаютсяна колонкитаблиц,должныбытьвиртуальными(особенность реализацииNH).

  16. NHibernate.Пример. ЧастьXML-файла,котораяотвечаетзаотображение данныхизтаблицыLanguageнакласс Books.Domain.Language,имеетследующийвид: <classname="Books.Domain.Language,NHibernateDemo" table="Language"> <idname="Id"type="System.Int32"> <columnname="Id"not-null="true"/> <generatorclass="identity"/> </id> <propertyname="Name"column="Name"/> </class>

  17. NHibernate.Пример. Ключевымиэлементамиконфигурации являются: <class>―связываетхранимыйклассс таблицейБД. <id>―связываетсвойствоклассас ключевойколонкойтаблицыБД. <property>―связываетсвойствоклассас колонкойтаблицыБД.

  18. NHibernate.Пример. ПерейдемкклассуAuthor.Обратимвнимание,что сущностиBookиAuthorнаходятсявотношении «многиекомногим»: namespaceBooks.Domain { publicclassAuthor { publicvirtualintId{get;set;} publicvirtualstringFirstName{get;set;} publicvirtualstringLastName{get;set;} publicvirtualintYearOfBirth{get;set;} publicvirtualIesi.Collections.Generic.ISet<Book>Books {get;set;} } }

  19. NHibernate.Пример. НастройкаотображениятаблицыAuthorна соответствующийклассбудетвыглядетьтак: <classname="Books.Domain.Author,NHibernateDemo"table="Author"> <idname="Id"type="System.Int32"> <columnname="Id"not-null="true"/> <generatorclass="identity"/> </id> <propertyname="FirstName"column="FirstName"/> <propertyname="LastName"column="LastName"/> <propertyname="YearOfBirth"type="System.Int32" column="YearOfBirth"/> <setname="Books"table="BookAuthor"> <keycolumn="AuthorId"></key> <many-to-manyclass="Books.Domain.Book,NHibernateDemo" column="BookId"></many-to-many> </set> </class>

  20. NHibernate.Пример. NHibernateпредоставляетнаборатрибутовдляотображения связеймеждутаблицамивсписки. <set>―управляетотображениемданныхвсвойстватипаISet илиISet<T>(коллекциибезотношенияпорядка,не допускающиедубликаты). <list>―управляетотображениемданныхвсвойстватипа IListилиIList<T>(коллекциисотношениемпорядка, допускающиедубликаты).   КрометогоNHibenateподдерживаетсвязитипа: многиекомногим; одинкомногим; многиекодному.   

  21. NHibernate.Пример. РассмотримклассBook,которыйимеетвнешнийключ натаблицуLanguage: namespaceBooks.Domain { publicclassBook { publicvirtualintId{get;set;} publicvirtualstringTitle{get;set;} publicvirtualLanguageOriginalLanguage {get;set;} } }

  22. NHibernate.Пример. НастройкаотображениятаблицыBookна соответствующийклассбудетвыглядетьтак: <classname="Books.Domain.Book,NHibernateDemo"table="Book"> <idname="Id"type="System.Int32"> <columnname="Id"not-null="true"/> <generatorclass="identity"/> </id> <propertyname="Title"column="Title"/> <many-to-onename="OriginalLanguage" column="OriginalLanguageId" class="Books.Domain.Language,NHibernateDemo"/> </class>

  23. NHibernate.Пример. Теперьрассмотрим,какпослеопределения отображениятаблицнадоменныеклассы оперироватьсданнымивэтихтаблицах. КлючевымисущностямиNHibernateявляются: ISessionFactory―объект,создаваемыйв одномэкземпляренабазуданных. ISession―ключевойобъектдляоперацийнад данными.Позволяетполучатьисохранять информацию. ITransaction―инкапсулируеттранзакциибазы данных.   

  24. Началоработы Передтемкакначатьоперациисбазойданных, необходимокнейподключиться.Дляэтогопотребуется определитьконтекстдляNHibernate.Сделаемэто определивконфигурационныйфайлNHibernate: <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2"> <session-factory> <propertyname="connection.driver_class"> NHibernate.Driver.SqlClientDriver </property> <propertyname="connection.connection_string"> Server=(local);initialcatalog=books_nhibernate </property> <propertyname="dialect"> NHibernate.Dialect.MsSql2008Dialect </property> </session-factory> </hibernate-configuration>

  25. NHibernate.Пример. Рассмотримсозданиепростейшегоприложения,котороевыводит списоквсехкниг,имеющихсявбазеданных: publicvoidShowBooks() { Configurationconfiguration=newConfiguration(); configuration.Configure(); configuration.AddAssembly("NHiberanteDemo"); ISessionFactoryfactory=configuration.BuildSessionFactory(); ISessionsession=factory.OpenSession(); //создаёмзапрос IQueryquery=session.CreateQuery("fromBook"); //выполняемзапросиполучаемданные IListbooks=query.List(); foreach(Bookbookinbooks) Console.WriteLine(book.Title); }

  26. ПостроениезапросовкБД ДляпостроениязапросовкБДNHibernate предоставляетнесколькомеханизмов: CriteriaAPI HQL QBE

  27. CriteriaAPI РассмотримпримерзапросакБДспомощьюCriteria API: publicvoidShowBooks() { Configurationconfiguration=newConfiguration(); configuration.Configure(); configuration.AddAssembly("NHiberanteDemo"); ISessionFactoryfactory=configuration.BuildSessionFactory(); ISessionsession=factory.OpenSession(); ICriteriacriteria=session.CreateCriteria(typeof(Book)); criteria.SetMaxResults(40); IListbooks=criteria.List(); foreach(Bookbookinbooks) Console.WriteLine(book.Title); IListbooksStartWithA= session.CreateCriteria(typeof(Book)) .Add(Restrictions.Like("Title","A%")) .List(); foreach(BookbookinbooksStartWithA) Console.WriteLine(book.Title); }

  28. HQL HQL(HibernateQueryLanguage)―SQL-подобныйязык запросов,используемыйвбиблиотекеHibernate. РассмотримпримерыиспользованияHQLдля полученияданных: publicvoidShowNumberOfBooks() { Configurationconfiguration=newConfiguration(); configuration.Configure(); configuration.AddAssembly("NHiberanteDemo"); ISessionFactoryfactory=configuration.BuildSessionFactory(); ISessionsession=factory.OpenSession(); IQueryquery=session.CreateQuery("selectcount(*)fromBook"); intbookCount=(int)query.UniqueResult(); Console.WriteLine(bookCount); }

  29. QBE QBE(QueryByExample)―механизмполучениягруппы объектовпохожихнапредоставленныйобъект. Примериспользования: publicvoidQBEExample(ISessionsession) { AuthorexampleAuthor=newAuthor(); exampleAuthor.FirstName="Лев"; exampleAuthor.LastName="Тостой"; IListresults= session.CreateCriteria(typeof(Author)) .Add(Example.Create(exampleAuthor)) .List(); foreach(Authorauthorinresults) Console.WriteLine(author.FirstName+""+author.LastName); }

  30. Модификацияданных Модификацияданныхосуществляетсяприпомощиобъектасессии имеханизматранзакций: publicvoidAddAuthorAndBook(Configurationconfiguration) { ISessionFactoryfactory=configuration.BuildSessionFactory(); ISessionsession=factory.OpenSession(); ITransactiontransaction=session.BeginTransaction(); BooknewBook=newBook(); newBook.Title="Надпропастьюворжи"; session.Save(newBook); AuthornewAuthor=newAuthor(); newAuthor.FirstName="Джером"; newAuthor.LastName="Сэлинджер"; newAuthor.Books.Add(newBook); session.Save(newAuthor); transaction.Commit(); session.Close(); }

  31. Doctrine Doctrine—ORM-решениедляязыкаPHP. ОднойизключевыхвозможностейDoctrine являетсязаписьзапросовкБДнасобственном объектно-ориентированномдиалектеDQL (DoctrineQueryLanguage),которыйбазируется наидеяхHQL. Начинаясверсии2.0,требуетPHP5.3+. Текущаяверсия:2.0.1

  32. Doctrine.Началоработы ПроцессиспользованияDoctrineсостоитиз следующихэтапов: Определениеконфигурацииподключения кБД. Определениедоменныхклассов,которые будутотображатьсянатаблицыБД. Написаниеконфигурационныхmapping файлов(XMLилиYAML). ПодключениекБДиманипуляция даннымивтерминахдоменныхклассов.

  33. КонфигурацияDoctrine Процессконфигурированиясостоитиз несколькихчастей: Запускавтозагрузкиклассов. Определениекаталогадлягенерации Proxy-классов. ОпределениетипаMapping-файлов. Определениепараметровподключения.    

  34. КонфигурацияDoctrine Запускавтозагрузки классовиопределение каталогадлягенерации Proxy-классов: $classLoader=new\Doctrine\Common\ClassLoader('Doctrine','doctrine-orm'); $classLoader->register(); $config=newDoctrine\ORM\Configuration(); $config->setProxyDir('proxies'); $config->setProxyNamespace('DoctrineDemo\Proxies'); $config->setAutoGenerateProxyClasses(true);

  35. КонфигурацияDoctrine Автозагрузкаклассов—этоноваявозможностьPHP5,которая позволяетподключатьфайлысклассамипомереих необходимости.Этавозможностьреализуетсяпутѐмрегистрации callback-функции,котораявызывается,еслибылобнаруженне определѐнныйранеекласс. Следующаястрокасоздаѐткласс,которыйотвечаетзазагрузку классовDoctrine: $classLoader=new\Doctrine\Common\ClassLoader('Doctrine','doctrine-orm'); Первымпараметромконструкторклассапринимаетпространство имѐн,вкоторомнаходятсяклассыDoctrine.Вторымпараметром являетсяпуть,покоторомунаходитсябиблиотека. Следующийвызоврегистрируетcallback-функциюзагрузки классов,предоставляемуюуказаннымвышеклассом: $classLoader->register();

  36. КонфигурацияDoctrine Дляреализации«ленивой»загрузкиданныхDoctrineгенерирует специальныеproxy-классы,которыезагружаютданныепомере обращенияксвойствамсоответствующихдоменныхклассов. Конфигурациятребуетопределитькаталог,вкоторыйбудут генерироватьсяproxy-классы,ипространствоимѐн,вкоторомони будутнаходиться: $config->setProxyDir('proxies'); $config->setProxyNamespace('DoctrineDemo\Proxies'); Следующеесвойствоопределяетбудутлиproxy-классы генерироватьсякаждыйраз,когдавнихвозникаетнеобходимость илинет: $config->setAutoGenerateProxyClasses(true); Этосвойствонеобходимоустановитьвfalse,приразвертывании приложения,чтобыизбежатьнакладныхрасходовсвязанныхс генерациейproxy-классов.

  37. КонфигурацияDoctrine DoctrineподдерживаетMapping-файлывформатах XMLиYAML. YAML(YAMLAin'tMarkupLanguage)—человекочитаемый форматсериализацииданных. Соответствующиетипыопределяютсяследующим образом: //ОпределениеXMLMappingфайлов $driverImpl= newDoctrine\ORM\Mapping\Driver\XmlDriver("mappings/xml"); //ОпределениеYAMLMappingфайлов $driverImpl= newDoctrine\ORM\Mapping\Driver\YamlDriver("mappings/yml"); $config->setMetadataDriverImpl($driverImpl);

  38. КонфигурацияDoctrine Mapping-файлыдолжнынаходитсявуказанныхкаталогах. ИменаMapping-файловдляXMLиYAMLформатовдолжны быть*.dcm.xmlи*.dcm.ymlсоответственно.

  39. YAML Языкизначальнобылзадуманкакязыкразметкиидажерассматривался какконкурентXML,однакопозжесталиспользоватьсявосновномкак форматконфигурационныхфайлов.СинтаксисYAMLминимален,особенно посравнениюссинтаксисомXML. РассмотримXML-файл,которыйхранитсвойстваподключенийкБД: <?xmlversion="1.0"encoding="utf-8"?> <connections> <connectionname="connection01"> <host>localhost</host> <database>MyDB</database> <password>root</password> <login>root</login> </connection> <connectionname="connection02"> <host>192.168.0.1</host> <database>production</database> <password>sb593f4s</password> <login>ds8(dg#1a</login> </connection> </connections>

  40. YAML ДревовиднаяструктураYAMLопределяетсяприпомощиотступов. АналогичнаяинформацияспомощьюYAMLможетбытьзаписана следующимобразом: -connection:connection01 host:localhost database:MyDB password:root login:root -connection:connection02 host:192.168.0.1 database:production password:sb593f4s login:ds8(dg#1a Болееподробнооязыке:http://yaml.org/

  41. КонфигурацияDoctrine Определениепараметровподключения: $connection=array( 'driver'=>'pdo_mysql', 'host'=>'localhost', 'dbname'=>'doctrine_demo', 'user'=>'root', 'password'=>'root' ); $entityManager=\Doctrine\ORM\EntityManager::create($connection,$config); Doctrineподдерживаетследующиетипыдраверов: pdo_mysql pdo_sqlite pdo_pgsql pdo_oci oci8     

  42. Doctrine.Пример Определимдоменныеклассы.Класскнигибудет выглядетьследующимобразом: classBook { private$id; private$title; private$originalLanguage; publicfunctiongetId(){return$this->id;} publicfunctionsetId($id){$this->id=$id;} publicfunctiongetTitle(){return$this->title;} publicfunctionsetTitle($title){$this->title=$title;} publicfunctiongetOriginalLanguage() {return$this->originalLanguage;} publicfunctionsetOriginalLanguage($originalLanguage) {$this->originalLanguage=$originalLanguage;} }

  43. Doctrine.Пример Класс,определяющийсущностьязыка: classLanguage { private$id; private$name; publicfunctiongetId(){return$this->id;} publicfunctionsetId($id){$this->id=$id;} publicfunctiongetName(){return$this->name;} publicfunctionsetName($name){$this->name=$name;} }

  44. Doctrine.Пример Класс,определяющийавтора: classAuthor { private$id; private$firstName; private$lastName; private$yearOfBirth; private$books; publicfunction__construct() { $this->books=array(); } publicfunctiongetId(){return$this->id;} publicfunctionsetId($id){$this->id=$id;} //... publicfunctiongetBooks(){return$this->books;} }

  45. Doctrine.Пример ОпределимXML-файл,отображающийсущностьязыка насоответствующуютаблицу: <doctrine-mapping xmlns="http://doctrine-project.org/schemas/orm/doctrine-mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation= "http://doctrine-project.org/schemas/orm/doctrine-mapping http://doctrine-project.org/schemas/orm/doctrine-mapping.xsd"> <entityname="Language"table="language"> <idname="id"type="integer"> <generatorstrategy="AUTO"/> </id> <fieldname="name"type="string"/> </entity> </doctrine-mapping>

  46. Doctrine.Пример АналогичныйYAMLфайлбудетследующим: Language: type:entity table:language id: id: type:integer generator: strategy:AUTO fields: name: type:string length:100

  47. Doctrine.Пример ОпределимXML-файл,отображающийсущностькниги насоответствующуютаблицу: <doctrine-mapping...> <entityname="Book"table="book"> <idname="id"type="integer"> <generatorstrategy="AUTO"/> </id> <fieldname="title"type="string"/> <many-to-onefield="originalLanguage"target-entity="Language"> <join-columnname="original_language_id"referenced-column-name="id"/> </many-to-one> </entity> </doctrine-mapping>

  48. Doctrine.Пример ОпределимXML-файл,отображающийсущностьавторана соответствующуютаблицу: <doctrine-mapping ...> <entityname="Author"table="author"> <idname="id"type="integer"> <generatorstrategy="AUTO"/> </id> <fieldname="firstName"column="first_name"type="string"/> <fieldname="lastName"column="last_name"type="string"/> <fieldname="yearOfBirth"column="year_of_birth"type="integer"/> <many-to-manyfield="books"target-entity="Book"> <join-tablename="book_author"> <join-columns> <join-columnname="author_id"referenced-column-name="id"/> </join-columns> <inverse-join-columns> <join-columnname="book_id"referenced-column-name="id"/> </inverse-join-columns> </join-table> </many-to-many> </entity> </doctrine-mapping>

  49. Doctrine.Пример Рассмотримпростейшийслучайполученияданныхиз базы: $entityManager=\Doctrine\ORM\EntityManager::create($connection,$config); $author=$entityManager->find("Author",1); echo$author->getFirstName().''.$author->getLastName(); foreach($author->getBooks()as$book) echo$book->getTitle();

  50. Doctrine.Пример Основныеманипуляциисданнымивыполняютсяпри помощиязыкаDQL: $booksQuery=$entityManager->createQuery( "SELECTbFROMBookbWHEREb.titleLIKE'В%'"); $booksQuery->setMaxResults(30); $books=$booksQuery->getResult(); foreach($booksas$book) echo$book->getTitle();

More Related