在开始之前,我们先创建一个名为MemberManaged的实体
MemberManaged.h
@interface MemberManaged : NSManagedObject @property ( nonatomic, retain) NSString * memberID; @property ( nonatomic, retain) NSString * mobilePhone; @property ( nonatomic, retain) NSDate * createDate; @property ( nonatomic, retain) NSNumber * goldNumber; @property ( nonatomic, retain) NSNumber * age; @property ( nonatomic, retain) NSNumber * isVip; @property ( nonatomic, retain) NSString * url;
快速入门后续的例子都是以此实体进行数据库的操作
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [MagicalRecord setupAutoMigratingCoreDataStack]; // ... return YES; } - (void)applicationWillTerminate:(UIApplication *)application { [MagicalRecord cleanUp]; }
查找数据
//返回MemberManaged表中的第一条数据 MemberManaged *memberManaged = [MemberManaged MR_findFirst];
//返回MemberManaged表中的所有数据 NSArray *array = [[MemberManaged MR_findAll];
//键值条件查找,返回符合条件的所有数据 NSArray *array = [MemberManaged MR_findByAttribute:@ "memberID" withValue:@ "1"];
//按指定字段排序 NSArray *array = [MemberManaged MR_findAllSortedBy: @"age" ascending: YES];
//自定义NSPredicate查找,返回符合条件的所有数据 NSPredicate *pre = [NSPredicate predicateWithFormat:@ "age > 18"]; MemberManaged *memberManaged = [MemberManaged MR_findAllWithPredicate:pre];
插入数据
对于NSPredicate不熟悉的同学可以看我之前写的介绍NSPredicate的博文,关于其他的查找方法我就不一一介绍了。
[MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { MemberManaged *memberManaged = [MemberManaged MR_createInContext:localContext]; memberManaged.memberID = @"1"; memberManaged.mobilePhone = @"xxxxxxxx"; memberManaged.createDate = [NSDate date]; memberManaged.goldNumber = @2; memberManaged.age = @18; memberManaged.url = @"http://bawn.github.io/"; memberManaged.isVip = @YES; } completion:^(BOOL success, NSError *error) { // ... }];
删除数据
//删除单条数据 [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { MemberManaged *member = [MemberManaged MR_findFirstInContext:localContext]; [member MR_deleteEntity]; } completion:^(BOOL success, NSError *error) { // ... }];
//删除表 [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { [MemberManaged MR_truncateAllInContext:localContext]; } completion:^(BOOL success, NSError *error) { // ... }];
更新数据
MemberManaged *member = [MemberManaged MR_findFirst]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { MemberManaged *localMember = [member MR_inContext:localContext]; localMember.age = @22; } completion:^(BOOL success, NSError *error) { // ... }];
为什么不用[NSManagedObjectContext save:]方法,请看博客
上一篇博文中提到Mantle的<MTLManagedObjectSerializing>协议,此协议有两个必须实现的方法:
//返回此类对应的实体类名 + (NSString *)managedObjectEntityName;
//返回此类和实体属性的映射关系 + (NSDictionary *)managedObjectKeysByPropertyKey;
另外由于Member类和MemberManaged类的url字段的类型不一致,需要实现另一个协议方法,实现NSUrl—>NSString(age和isVip字段不需要转换,不要问我为什么)
//属性值转换 + (NSValueTransformer *)entityAttributeTransformerForKey:(NSString *)key;
先看具体实现
Member.h
@interface Member : MTLModel<MTLJSONSerializing, MTLManagedObjectSerializing> @property (nonatomic, retain) NSString * memberID; @property (nonatomic, retain) NSString * mobilePhone; @property (nonatomic, retain) NSDate * createDate; @property (nonatomic, retain) NSNumber *goldNumber; @property (nonatomic, assign) NSUInteger age; @property (nonatomic, assign) BOOL isVip; @property (nonatomic, retain) NSURL *url;
Member.m
//表示Member类对应的实体类是MemberManaged + (NSString *)managedObjectEntityName{ return @"MemberManaged"; }
//表示Member类向MemberManaged类转换的字段映射,因为Member类的字段名是相同,所以这里返回nil + (NSDictionary *)managedObjectKeysByPropertyKey{ return nil; }
//表示Member的url向MemberManaged的url字段值转换 + (NSValueTransformer *)entityAttributeTransformerForKey:(NSString *)key{ if ([key isEqualToString:@"url"]) { return [MTLValueTransformer reversibleTransformerWithBlock:^id(NSURL *url) { return url.absoluteString; }]; } else{ return nil; } }
具体运用:
NSDictionary *dic = @{@"id" : @"1", @"phone" : @"xxxxxxxx", @"date" : @"2014-09-09", @"goldNumber" : @2, @"age" : @"28", @"url" : @"http://bawn.github.io/", @"isVip" : NSNull.null }; Member *member = [MTLJSONAdapter modelOfClass:[Member class] fromJSONDictionary:dic error:nil]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { [MTLManagedObjectAdapter managedObjectFromModel:member insertingIntoContext:localContext error:nil]; } completion:^(BOOL success, NSError *error) { NSLog(@"%@", [(MemberManaged *)[MemberManaged MR_findFirst] isVip]); }];
注意:对于MemberManaged类,我们并不需要对它做任何的处理。
同样是实现<MTLManagedObjectSerializing>中的一个方法:
+ (NSSet *)propertyKeysForManagedObjectUniquing{ return [NSSet setWithObject:@"memberID"]; }
执行一下代码表示当插入新数据的时候,对比需要插入的这条数据的memberID字段的值是否和数据库中的有相同。如果有相同就覆盖更新这条数据,如果没有就新增。这样带来的方便之处显而易见。
for (int n = 0; n < 2; n++) { NSDictionary *dic = @{@"id" : @"1", @"phone" : @"xxxxxxxx", @"date" : @"2014-09-09", @"goldNumber" : @2, @"age" : @"18", @"url" : @"http://bawn.github.io/", @"isVip" : NSNull.null }; Member *member = [MTLJSONAdapter modelOfClass:[Member class] fromJSONDictionary:dic error:nil]; [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) { [MTLManagedObjectAdapter managedObjectFromModel:member insertingIntoContext:localContext error:nil]; } completion:^(BOOL success, NSError *error) { NSLog(@"%d", [(MemberManaged *)[MemberManaged MR_findFirst] isVip].boolValue); }]; }
数据库中只有一条数据,因为插入的数据的memberID都是2。
MagicalRecord配合Mantle使用至少让代码看起来简洁了不少,再也不用为Core Data复杂的API而烦恼,也不用再写if/else来做字段的转换。
Demo地址:MagicalRecord-Mantle