SlideShare a Scribd company logo
ActiveRecord for Core Data




          AZOFT
Что такое ActiveRecord?
ActiveRecord - паттерн, описанный Мартином Фаулером в книге
«Patterns of Enterprise Application Architecture» (Шаблоны
корпоративных приложений). AR является популярным
способом доступа к данным реляционных баз данных в
объектно-ориентированном программировании.


Объект, выполняющий роль оболочки для строки таблицы или
представления базы данных. Он инкапсулирует доступ к базе
данных и добавляет к данным логику домена.
●   Пусть существует таблица в базе данных. Для данной
    таблицы создаётся специальный класс AR, являющийся
    отражением (представлением) таблицы, таким образом,
    что:
●   каждый экземпляр данного класса соответствует одной
    записи таблицы;
●   при создании нового экземпляра класса (и заполнении
    соответствующих полей) в таблицу добавляется новая
    запись;
●   при чтении полей объекта считываются соответствующие
    значения записи таблицы баз данных;
●   при изменении (удалении) какого-либо объекта
    изменяется (удаляется) соответствующая ему запись.
Core Data и Active Record
Core Data основана на паттерне Active Record, но для работы с
базой данных приходится писать довольно громоздкий код.
Пример Apple:
 NSManagedObjectContext *moc = [self managedObjectContext];
 NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee"
 inManagedObjectContext:moc];
 NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
 [request setEntity:entityDescription];
 // Set example predicate and sort orderings...
 NSNumber *minimumSalary = ...;
 NSPredicate *predicate = [NSPredicate predicateWithFormat:
                  @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];
 [request setPredicate:predicate];
 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName"
                                         ascending:YES];
 [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];
 [sortDescriptor release];

 NSError *error = nil;
 NSArray *array = [moc executeFetchRequest:request error:&error];
 if (array == nil){
     // Deal with error...
 }
Как видно из примера для поиска в базе данных
  Сотрудников(Employee) у которых фамилия содержит
  «Worsley» и зарплата выше минимальной зарплаты приходится
  писать много «лишнего» кода.
  Решение данной проблемы предоставили Magical Panda в
  своей библиотеке ActiveRecord for Core Data
  Вот тот же пример, только с использованием ActiveRecord for
  CoreData(MagicalRecord):

NSNumber *minimumSalary = ...;
NSPredicate *predicate = [NSPredicate predicateWithFormat:
             @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary];
NSArray *employees = [Employee MR_findAllSortedBy:@"firstName"
                                      asceding:YES
                                  withPredicate:predicate];
ActiveRecord for Core Data позволяет:

1. Сделать чище код по работе с Core Data
2. Позволяет делать простые однострочные
запросы
3. Несмотря на простоту, позволяет
модифицировать NSFetchRequest, когда
запрос нуждается в модификации.
Примеры использования.
 Допустим есть класс Song с полями id, length и name:
@interface Song : NSManagedObject

@property (nonatomic, retain) NSNumber * length;

@property (nonatomic, retain) NSString * name;

@property (nonatomic, retain) NSNumber * unid;

@end



@implementation Song

@dynamic length;

@dynamic name;

@dynamic unid;

@end
Если необходимо найти все Song объекты в базе данных, то
вызов будет иметь следующий вид:
NSArray *songs = [Song MR_findAll];

Поиск песен, отсортированных по name будет иметь вид:

NSArray *songs = [Song MR_findAllSortedBy:@"name" ascending:YES];


Если есть песня с уникальным значением атрибута, то
можно воспользоваться функцией:

NSArray *songs = [Song MR_findFirstByAttribute:@"name" withValue:@"Imagine"];


Так же ActiveRecord for Core Data позволяет использовать
NSPredicate:

NSPredicate *songFilter = [NSPredicate predicateWithFormat:@"length > %@", @""];

NSArray *songs = [Song MR_findAllWithPredicate:songFilter];
Модификация   NSFetchRequest:
  NSPredicate *peopleFilter = [NSPredicate predicateWithFormat: @"Department IN
%@", departments];
  NSFetchRequest *peopleRequest = [Place requestAllWithPredicate:peopleFilter];
  [peopleRequest setReturnsDistinctResults:NO];
  [peopleRequest setReturnPropertiesNamed:[NSArray arrayWithObjects:@"FirstName",

        @"LastName", nil]];
  ...
  NSArray *people = [Place executeFetchRequest:peopleRequest];
Количество вхождений:
  NSNumber *count = [Place MR_numberOfEntities];
  NSNumber *count = [Place MR_numberOfEntitiesWithPredicate: ...];
Агрегатные операции:
  NSPredicate *prediate = [NSPredicate predicateWithFormat: ...];

   int totalFat = [[Place aggregateOperation:@"sum:" onAttribute:@"fatColories"
withPredicate:predicate] intValue];

   int fattest = [[Place aggregateOperation:@"max:" onAttribute:@"fatColories"
withPredicate:predicate] intValue];
Редактирование данных:
Создать запись в базе данных при помощи ActiveRecord for
Core Data очень просто:
Song *song = [Song MR_createEntity];
Занимает очень мало кода в отличии от этого примера:
Song *song = (Song *)[NSEntityDescription insertNewObjectForEntityForName:@"Song"
                insertNewObjectForEntityForName:[ self managedObjectContext]];
Удаление:
[song MR_deleteEntity];    [Song truncateAll];
Редактирование аттрибутов:
Song *song = [Song MR_createEntity];
song.name = @"stairway to heaven";
song.length = [NSNumber numberWithInt:150];
После редактирования данных необходимо сохранить контекст:
[[NSManagedObjectContext defaultContext] MR_save];
Подключение к проекту:
Добавляем в MyProjectName-Prefix.pch
#import "CoreData+ActiveRecordFetching.h"

В AppDelegate в application:didFinishLaunchingWithOptions: добавлям
вызов
[ActiveRecordHelpers

      setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"MyProject.sqlite"];

Данный метод создаст NSPersistentStore с указанным именем и файлом
модели .xcdatamodeld который найдет в бандле приложения.
Default Managed Object Context
При работе с Core Data используется объект
NSManagedObjectContext. ActiveRecord for Core Data позволяет
установить DefaultContext, который будет NSManagedObjectContext по-
умолчанию для всего приложения. Создание NSManagedObjectContext
для использования в других потоках выглядит следующим
образом:
NSManagedObjectContext *myNewContext = [NSManagedObjectContext newContext];

Этот контекст можно сделать по-умолчанию, и тогда он будет
использоваться во всех запросах, если в названии метода
запроса вконце не стоит «inContext:». Рекомендуется создавать и
устанавливать контекст по-умолчанию только в главном потоке.
Источники
●   https://github.com/magicalpanda/MagicalRecord
●   http://ru.wikipedia.org/wiki/ActiveRecord
●   http://habrahabr.ru/blogs/macosxdev/130262/
●   «Patterns of Enterprise Application Architecture» (англ.
    Шаблоны корпоративных приложений)

More Related Content

PPT
Интеграция Яндекс Сервер
PDF
Интуит. Разработка приложений для iOS. Лекция 8. Работа с данными
PPT
Yserver
PPTX
Вебинар Томулевича adjacency
PDF
Школа-студия разработки для iOS. Лекция 4. Работа с данными
PDF
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
PPT
Эффективное программирование на NodeJS
PPT
XML Native Database на примере SednaXML
Интеграция Яндекс Сервер
Интуит. Разработка приложений для iOS. Лекция 8. Работа с данными
Yserver
Вебинар Томулевича adjacency
Школа-студия разработки для iOS. Лекция 4. Работа с данными
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Эффективное программирование на NodeJS
XML Native Database на примере SednaXML

What's hot (20)

PPTX
Stream API: рекомендации лучших собаководов
PPT
LDAP in infrastructure (RootConf 2009)
ODP
Контейнеры и хранение объектов в ООП
PDF
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
PDF
13 - Hadoop. Парадигма Spark
PDF
06 - Hadoop. Java API и Hadoop Streaming
PPTX
Мастер класс по алгоритмам. Часть 1
ODP
Alexander Dymo - Barcamp 2009 - Faster Higher Sql
PDF
Разработка на Perl под Raspberry PI
PDF
RDSDataSource: YapDatabase
PPTX
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
PDF
Паттерны и примеры структур данных в NoSQL на примере Tarantool
PPT
Импорт данных с фреймворком Migrate. Владислав Богатырев.
PDF
Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...
ODP
Работа с БД в Drupal 7
PDF
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
PDF
Расширенное кеширование в Doctrine2
PPTX
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
PPTX
Программирование на PySpark
PDF
08 - Hadoop. Алгоритмы на графах в MapReduce
Stream API: рекомендации лучших собаководов
LDAP in infrastructure (RootConf 2009)
Контейнеры и хранение объектов в ООП
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
13 - Hadoop. Парадигма Spark
06 - Hadoop. Java API и Hadoop Streaming
Мастер класс по алгоритмам. Часть 1
Alexander Dymo - Barcamp 2009 - Faster Higher Sql
Разработка на Perl под Raspberry PI
RDSDataSource: YapDatabase
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
Паттерны и примеры структур данных в NoSQL на примере Tarantool
Импорт данных с фреймворком Migrate. Владислав Богатырев.
Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...
Работа с БД в Drupal 7
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Расширенное кеширование в Doctrine2
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
Программирование на PySpark
08 - Hadoop. Алгоритмы на графах в MapReduce
Ad

Similar to Active Record for CoreData (20)

PDF
Things you might have missed from CoreData
PPTX
Введение в Realm.io
PDF
хранение данных
PDF
#MBLTdev: Core Data: особенности использования и синхронизация в iCloud (Avia...
PDF
Влад Ковташ — Yap Database
PPTX
Coding like a sex
PPTX
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
PPTX
Record. Интерфейс
PPTX
Record. Краткий обзор
PDF
Фундаментальные основы разработки под iOS. Павел Тайкало
PDF
Squeek 1
PPTX
DBD lection 2. Requirements for DBA in RF, normalization rules, basics of SQL...
PPT
Talks on collections
PPT
Уровни проектирования информационной системы (обзор материалов портала wiki....
PDF
C# Web. Занятие 04.
PPTX
Есть ли жизнь с ORM или типовая архитектура CRUD приложения
PPT
Rose::DB
PDF
msumobi2. Лекция 2
PDF
Java Persistence API (JPA) Basics
PDF
CQRS на практике. В поиске точки масштабирования и новых метафор
Things you might have missed from CoreData
Введение в Realm.io
хранение данных
#MBLTdev: Core Data: особенности использования и синхронизация в iCloud (Avia...
Влад Ковташ — Yap Database
Coding like a sex
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
Record. Интерфейс
Record. Краткий обзор
Фундаментальные основы разработки под iOS. Павел Тайкало
Squeek 1
DBD lection 2. Requirements for DBA in RF, normalization rules, basics of SQL...
Talks on collections
Уровни проектирования информационной системы (обзор материалов портала wiki....
C# Web. Занятие 04.
Есть ли жизнь с ORM или типовая архитектура CRUD приложения
Rose::DB
msumobi2. Лекция 2
Java Persistence API (JPA) Basics
CQRS на практике. В поиске точки масштабирования и новых метафор
Ad

Active Record for CoreData

  • 2. Что такое ActiveRecord? ActiveRecord - паттерн, описанный Мартином Фаулером в книге «Patterns of Enterprise Application Architecture» (Шаблоны корпоративных приложений). AR является популярным способом доступа к данным реляционных баз данных в объектно-ориентированном программировании. Объект, выполняющий роль оболочки для строки таблицы или представления базы данных. Он инкапсулирует доступ к базе данных и добавляет к данным логику домена.
  • 3. Пусть существует таблица в базе данных. Для данной таблицы создаётся специальный класс AR, являющийся отражением (представлением) таблицы, таким образом, что: ● каждый экземпляр данного класса соответствует одной записи таблицы; ● при создании нового экземпляра класса (и заполнении соответствующих полей) в таблицу добавляется новая запись; ● при чтении полей объекта считываются соответствующие значения записи таблицы баз данных; ● при изменении (удалении) какого-либо объекта изменяется (удаляется) соответствующая ему запись.
  • 4. Core Data и Active Record Core Data основана на паттерне Active Record, но для работы с базой данных приходится писать довольно громоздкий код. Пример Apple: NSManagedObjectContext *moc = [self managedObjectContext]; NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc]; NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease]; [request setEntity:entityDescription]; // Set example predicate and sort orderings... NSNumber *minimumSalary = ...; NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary]; [request setPredicate:predicate]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; [sortDescriptor release]; NSError *error = nil; NSArray *array = [moc executeFetchRequest:request error:&error]; if (array == nil){ // Deal with error... }
  • 5. Как видно из примера для поиска в базе данных Сотрудников(Employee) у которых фамилия содержит «Worsley» и зарплата выше минимальной зарплаты приходится писать много «лишнего» кода. Решение данной проблемы предоставили Magical Panda в своей библиотеке ActiveRecord for Core Data Вот тот же пример, только с использованием ActiveRecord for CoreData(MagicalRecord): NSNumber *minimumSalary = ...; NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(lastName LIKE[c] 'Worsley') AND (salary > %@)", minimumSalary]; NSArray *employees = [Employee MR_findAllSortedBy:@"firstName" asceding:YES withPredicate:predicate];
  • 6. ActiveRecord for Core Data позволяет: 1. Сделать чище код по работе с Core Data 2. Позволяет делать простые однострочные запросы 3. Несмотря на простоту, позволяет модифицировать NSFetchRequest, когда запрос нуждается в модификации.
  • 7. Примеры использования. Допустим есть класс Song с полями id, length и name: @interface Song : NSManagedObject @property (nonatomic, retain) NSNumber * length; @property (nonatomic, retain) NSString * name; @property (nonatomic, retain) NSNumber * unid; @end @implementation Song @dynamic length; @dynamic name; @dynamic unid; @end
  • 8. Если необходимо найти все Song объекты в базе данных, то вызов будет иметь следующий вид: NSArray *songs = [Song MR_findAll]; Поиск песен, отсортированных по name будет иметь вид: NSArray *songs = [Song MR_findAllSortedBy:@"name" ascending:YES]; Если есть песня с уникальным значением атрибута, то можно воспользоваться функцией: NSArray *songs = [Song MR_findFirstByAttribute:@"name" withValue:@"Imagine"]; Так же ActiveRecord for Core Data позволяет использовать NSPredicate: NSPredicate *songFilter = [NSPredicate predicateWithFormat:@"length > %@", @""]; NSArray *songs = [Song MR_findAllWithPredicate:songFilter];
  • 9. Модификация   NSFetchRequest: NSPredicate *peopleFilter = [NSPredicate predicateWithFormat: @"Department IN %@", departments]; NSFetchRequest *peopleRequest = [Place requestAllWithPredicate:peopleFilter]; [peopleRequest setReturnsDistinctResults:NO]; [peopleRequest setReturnPropertiesNamed:[NSArray arrayWithObjects:@"FirstName", @"LastName", nil]]; ... NSArray *people = [Place executeFetchRequest:peopleRequest]; Количество вхождений: NSNumber *count = [Place MR_numberOfEntities]; NSNumber *count = [Place MR_numberOfEntitiesWithPredicate: ...]; Агрегатные операции: NSPredicate *prediate = [NSPredicate predicateWithFormat: ...]; int totalFat = [[Place aggregateOperation:@"sum:" onAttribute:@"fatColories" withPredicate:predicate] intValue]; int fattest = [[Place aggregateOperation:@"max:" onAttribute:@"fatColories" withPredicate:predicate] intValue];
  • 10. Редактирование данных: Создать запись в базе данных при помощи ActiveRecord for Core Data очень просто: Song *song = [Song MR_createEntity]; Занимает очень мало кода в отличии от этого примера: Song *song = (Song *)[NSEntityDescription insertNewObjectForEntityForName:@"Song" insertNewObjectForEntityForName:[ self managedObjectContext]]; Удаление: [song MR_deleteEntity]; [Song truncateAll]; Редактирование аттрибутов: Song *song = [Song MR_createEntity]; song.name = @"stairway to heaven"; song.length = [NSNumber numberWithInt:150]; После редактирования данных необходимо сохранить контекст: [[NSManagedObjectContext defaultContext] MR_save];
  • 11. Подключение к проекту: Добавляем в MyProjectName-Prefix.pch #import "CoreData+ActiveRecordFetching.h" В AppDelegate в application:didFinishLaunchingWithOptions: добавлям вызов [ActiveRecordHelpers setupCoreDataStackWithAutoMigratingSqliteStoreNamed:@"MyProject.sqlite"]; Данный метод создаст NSPersistentStore с указанным именем и файлом модели .xcdatamodeld который найдет в бандле приложения.
  • 12. Default Managed Object Context При работе с Core Data используется объект NSManagedObjectContext. ActiveRecord for Core Data позволяет установить DefaultContext, который будет NSManagedObjectContext по- умолчанию для всего приложения. Создание NSManagedObjectContext для использования в других потоках выглядит следующим образом: NSManagedObjectContext *myNewContext = [NSManagedObjectContext newContext]; Этот контекст можно сделать по-умолчанию, и тогда он будет использоваться во всех запросах, если в названии метода запроса вконце не стоит «inContext:». Рекомендуется создавать и устанавливать контекст по-умолчанию только в главном потоке.
  • 13. Источники ● https://github.com/magicalpanda/MagicalRecord ● http://ru.wikipedia.org/wiki/ActiveRecord ● http://habrahabr.ru/blogs/macosxdev/130262/ ● «Patterns of Enterprise Application Architecture» (англ. Шаблоны корпоративных приложений)