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

What's hot

Stream API: рекомендации лучших собаководов
Stream API: рекомендации лучших собаководовStream API: рекомендации лучших собаководов
Stream API: рекомендации лучших собаководов
tvaleev
 
LDAP in infrastructure (RootConf 2009)
LDAP in infrastructure (RootConf 2009)LDAP in infrastructure (RootConf 2009)
LDAP in infrastructure (RootConf 2009)
Sergey Skvortsov
 
Контейнеры и хранение объектов в ООП
Контейнеры и хранение объектов в ООПКонтейнеры и хранение объектов в ООП
Контейнеры и хранение объектов в ООПitclub_kz
 
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru GroupКак не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Как не сделать врагами архитектуру и оптимизацию, Кирилл Березин, Mail.ru Group
Mail.ru Group
 
13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма Spark13 - Hadoop. Парадигма Spark
13 - Hadoop. Парадигма Spark
Roman Brovko
 
06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop Streaming06 - Hadoop. Java API и Hadoop Streaming
06 - Hadoop. Java API и Hadoop Streaming
Roman Brovko
 
Мастер класс по алгоритмам. Часть 1
Мастер класс по алгоритмам. Часть 1Мастер класс по алгоритмам. Часть 1
Мастер класс по алгоритмам. Часть 1
Pavel Egorov
 
Alexander Dymo - Barcamp 2009 - Faster Higher Sql
Alexander Dymo - Barcamp 2009 - Faster Higher SqlAlexander Dymo - Barcamp 2009 - Faster Higher Sql
Alexander Dymo - Barcamp 2009 - Faster Higher SqlAlexander Dymo
 
Разработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PIРазработка на Perl под Raspberry PI
Разработка на Perl под Raspberry PI
Ilya Chesnokov
 
RDSDataSource: YapDatabase
RDSDataSource: YapDatabaseRDSDataSource: YapDatabase
RDSDataSource: YapDatabase
RAMBLER&Co
 
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"СУБД 2013 Лекция №8 "Конфигурирование базы данных"
СУБД 2013 Лекция №8 "Конфигурирование базы данных"
Technopark
 
Паттерны и примеры структур данных в NoSQL на примере Tarantool
Паттерны и примеры структур данных в NoSQL на примере TarantoolПаттерны и примеры структур данных в NoSQL на примере Tarantool
Паттерны и примеры структур данных в NoSQL на примере Tarantool
Alexandre Kalendarev
 
Импорт данных с фреймворком Migrate. Владислав Богатырев.
Импорт данных с фреймворком Migrate. Владислав Богатырев.Импорт данных с фреймворком Migrate. Владислав Богатырев.
Импорт данных с фреймворком Migrate. Владислав Богатырев.DrupalCampDN
 
Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...
Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...
Встреча №8. NSIncrementalStore, или как заставить Core Data варить ваш собств...
CocoaHeads
 
Работа с БД в Drupal 7
Работа с БД в Drupal 7Работа с БД в Drupal 7
Работа с БД в Drupal 7
Eugene Fidelin
 
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Отказоустойчивая обработка 10M OAuth токенов на Tarantool / Владимир Перепели...
Ontico
 
Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2Расширенное кеширование в Doctrine2
Расширенное кеширование в Doctrine2
Ilyas Salikhov
 
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
СУБД 2013 Лекция №6 "Профилирование запросов. Сложноструктурированные SQL-зап...
Technopark
 
Программирование на PySpark
Программирование на PySparkПрограммирование на PySpark
Программирование на PySpark
RamblerML
 
08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduce08 - Hadoop. Алгоритмы на графах в MapReduce
08 - Hadoop. Алгоритмы на графах в MapReduce
Roman Brovko
 

What's hot (20)

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

Similar to Active Record for CoreData

хранение данных
хранение данныххранение данных
хранение данных
Noveo
 
Влад Ковташ — Yap Database
Влад Ковташ — Yap DatabaseВлад Ковташ — Yap Database
Влад Ковташ — Yap Database
CocoaHeads
 
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейс
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейсИнтуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейс
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейсГлеб Тарасов
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
Глеб Тарасов
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
Fedor Malyshkin
 
Курсы по мобильной разработке под iOS. 5 лекция. Работа с данными
Курсы по мобильной разработке под iOS. 5 лекция. Работа с даннымиКурсы по мобильной разработке под iOS. 5 лекция. Работа с данными
Курсы по мобильной разработке под iOS. 5 лекция. Работа с даннымиГлеб Тарасов
 
Паттерны проектирования источников данных
Паттерны проектирования источников данныхПаттерны проектирования источников данных
Паттерны проектирования источников данных
Alex Polorotov
 
паттерны проектирования источников данных
паттерны проектирования источников данныхпаттерны проектирования источников данных
паттерны проектирования источников данныхVitaliy Trenkenshu
 
Формальные методы защиты приложений
Формальные методы защиты приложенийФормальные методы защиты приложений
Формальные методы защиты приложений
Positive Hack Days
 
RxJava + Retrofit
RxJava + RetrofitRxJava + Retrofit
RxJava + Retrofit
Dev2Dev
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSГлеб Тарасов
 
Next Gen Applications
Next Gen ApplicationsNext Gen Applications
Next Gen Applications
Vittorio Cioe
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CГлеб Тарасов
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6Technopark
 
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Fedor Lavrentyev
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
CocoaHeads
 
Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. Databases
Sergey Nemchinsky
 
Kvc, kvo
Kvc, kvoKvc, kvo
Kvc, kvo
Noveo
 

Similar to Active Record for CoreData (20)

хранение данных
хранение данныххранение данных
хранение данных
 
Влад Ковташ — Yap Database
Влад Ковташ — Yap DatabaseВлад Ковташ — Yap Database
Влад Ковташ — Yap Database
 
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейс
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейсИнтуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейс
Интуит. Разработка приложений для iOS. Лекция 9. Нестандартный интерфейс
 
msumobi2. Лекция 1
msumobi2. Лекция 1msumobi2. Лекция 1
msumobi2. Лекция 1
 
Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)Документирование исходных текстов (javadoc)
Документирование исходных текстов (javadoc)
 
Курсы по мобильной разработке под iOS. 5 лекция. Работа с данными
Курсы по мобильной разработке под iOS. 5 лекция. Работа с даннымиКурсы по мобильной разработке под iOS. 5 лекция. Работа с данными
Курсы по мобильной разработке под iOS. 5 лекция. Работа с данными
 
Паттерны проектирования источников данных
Паттерны проектирования источников данныхПаттерны проектирования источников данных
Паттерны проектирования источников данных
 
паттерны проектирования источников данных
паттерны проектирования источников данныхпаттерны проектирования источников данных
паттерны проектирования источников данных
 
Формальные методы защиты приложений
Формальные методы защиты приложенийФормальные методы защиты приложений
Формальные методы защиты приложений
 
RxJava + Retrofit
RxJava + RetrofitRxJava + Retrofit
RxJava + Retrofit
 
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOSКурсы по мобильной разработке. 1 лекция. Знакомство с iOS
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
 
Next Gen Applications
Next Gen ApplicationsNext Gen Applications
Next Gen Applications
 
Js fuckworks
Js fuckworksJs fuckworks
Js fuckworks
 
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-CШкола-студия разработки приложений для iOS. Лекция 1. Objective-C
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
 
Nosql and Mongodb
Nosql and MongodbNosql and Mongodb
Nosql and Mongodb
 
Web осень 2013 лекция 6
Web осень 2013 лекция 6Web осень 2013 лекция 6
Web осень 2013 лекция 6
 
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
Industrial Programming Java - Lection Pack 03 - Relational Databases - Lavren...
 
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
Встреча №9. Алгоритмы и коллекции стандартных библиотек C++, C#, Java, Object...
 
Основы Java. 5. Databases
Основы Java. 5. DatabasesОсновы Java. 5. Databases
Основы Java. 5. Databases
 
Kvc, kvo
Kvc, kvoKvc, kvo
Kvc, kvo
 

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» (англ. Шаблоны корпоративных приложений)