CoreData详解
介绍:
在Cocoa环境下,如果你想使用数据库(如sqlite),你可以使用sql语句的方式通过相关的工具类进行数据库的直接操作。当然你也可以通过别人封装之后的一些简单框架,使得你的操作更加简单(如FMDB BNRPersistence)。
Cocoa框架本身提供了CoreData这个API可方便的让开发者通过操作对象的方式在操作数据库。CoreData是一个对象图(object graph)以及持久化的管理框架。我们可以通过CoreData创对象,设置好象之间的关系,然后将其持久化(我们甚至可以使用内存数据库),或者从硬盘上将持久化后的数据加载到内存中。对象图,我们可以创建一个个的对象,并维持不同对象之间的关系,一对一,一对多等。
CoreData有大量的特性,诸如支持Redo,Undo的功能,这些很多Document based的程序中显得非常的有用。提供数据model结构变化轻量级的迁移方案。CoreData还通过Binding特性和控件的紧密结合,这样使得只需要少量的代码便可以完成强大的功能,下面是一个例子
http://www.timisted.net/blog/archive/multiple-windows-with-core-data/
存储方式
Core Data可以将数据存储为XML,二进制文件或SQLite文件。在Mac OS X 10.5 Leopard及以后的版本中,开发者也可以通过继承NSPersistentStore类以创建自定义的存储格式。每种方法都有其优缺点,例如XML的可读性,SQLite的节约空间等。
Core Data的这一方面类似于原始的Enterprise Objects Framework(EOF)系统,但EOF中开发者可以使用相对简洁的查询方式,而在Core Data中,只能使用一个语法类似SQL子集的查询语言,称为Predicate。Core Data是标准化的,可以自由的读写Xcode数据模型文件(通常是.xcdatamodel文件)。
与EOF不同,Core Data目前没有设计多用户或多线程访问模式。模型迁移通常也需要代码,若其它开发者依赖于某个数据模型,则该数据模型的设计者可能在模型发生改变时需要与新数据模型一起提供版本转换代码。
操作简介
Core Data由相对庞大的类继承体系组成,但开发者需要关注的接口只是其中的一个相对小的子集。
一般需要定义以下Core Data的三个必备
NSPersistentStoreCoordinator *persistentStoreCoordinator;
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
以及使用时需要用到的
NSFetchedResultsController *fetchedResultsController;
还记得我们每次使用CoreData的时候系统都会给我们创建一些代码吗?
1 #pragma mark - Core Data 堆栈 2 //返回 被管理的对象上下文 3 - (NSManagedObjectContext *)managedObjectContext 4 { 5 if (_managedObjectContext) { 6 return _managedObjectContext; 7 } 8 9 NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 10 if (coordinator) { 11 _managedObjectContext = [[NSManagedObjectContext alloc] init]; 12 [_managedObjectContext setPersistentStoreCoordinator:coordinator]; 13 } 14 return _managedObjectContext; 15 } 16 17 // 返回 持久化存储协调者 18 - (NSPersistentStoreCoordinator *)persistentStoreCoordinator 19 { 20 if (_persistentStoreCoordinator) { 21 return _persistentStoreCoordinator; 22 } 23 24 NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataNotes.sqlite"]; 25 26 _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 27 28 [_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 29 configuration:nil 30 URL:storeURL 31 options:nil 32 error:nil]; 33 34 return _persistentStoreCoordinator; 35 } 36 37 // 返回 被管理的对象模型 38 - (NSManagedObjectModel *)managedObjectModel 39 { 40 if (_managedObjectModel) { 41 return _managedObjectModel; 42 } 43 NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreDataNotes" withExtension:@"momd"]; 44 _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 45 return _managedObjectModel; 46 } 47 48 #pragma mark - 应用程序沙箱 49 // 返回应用程序Docment目录的NSURL类型 50 - (NSURL *)applicationDocumentsDirectory 51 { 52 return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 53 }
下面是使用Core的示例代码
1 static NoteDAO *sharedManager = nil; 2 3 + (NoteDAO*)sharedManager 4 { 5 static dispatch_once_t once; 6 dispatch_once(&once, ^{ 7 8 sharedManager = [[self alloc] init]; 9 [sharedManager managedObjectContext]; 10 11 }); 12 return sharedManager; 13 } 14 15 16 //插入Note方法 17 -(int) create:(Note*)model 18 { 19 20 NSManagedObjectContext *cxt = [self managedObjectContext]; 21 22 NoteManagedObject *note = [NSEntityDescription insertNewObjectForEntityForName:@"Note" inManagedObjectContext:cxt]; 23 [note setValue: model.content forKey:@"content"]; 24 [note setValue: model.date forKey:@"date"]; 25 26 note.date = model.date; 27 note.content = model.content; 28 29 NSError *savingError = nil; 30 if ([self.managedObjectContext save:&savingError]){ 31 NSLog(@"插入数据成功"); 32 } else { 33 NSLog(@"插入数据失败"); 34 return -1; 35 } 36 37 return 0; 38 } 39 40 //删除Note方法 41 -(int) remove:(Note*)model 42 { 43 44 NSManagedObjectContext *cxt = [self managedObjectContext]; 45 46 NSEntityDescription *entityDescription = [NSEntityDescription 47 entityForName:@"Note" inManagedObjectContext:cxt]; 48 49 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 50 [request setEntity:entityDescription]; 51 52 NSPredicate *predicate = [NSPredicate predicateWithFormat: 53 @"date = %@", model.date]; 54 [request setPredicate:predicate]; 55 56 NSError *error = nil; 57 NSArray *listData = [cxt executeFetchRequest:request error:&error]; 58 if ([listData count] > 0) { 59 NoteManagedObject *note = [listData lastObject]; 60 [self.managedObjectContext deleteObject:note]; 61 62 NSError *savingError = nil; 63 if ([self.managedObjectContext save:&savingError]){ 64 NSLog(@"删除数据成功"); 65 } else { 66 NSLog(@"删除数据失败"); 67 return -1; 68 } 69 } 70 71 return 0; 72 } 73 74 //修改Note方法 75 -(int) modify:(Note*)model 76 { 77 NSManagedObjectContext *cxt = [self managedObjectContext]; 78 79 NSEntityDescription *entityDescription = [NSEntityDescription 80 entityForName:@"Note" inManagedObjectContext:cxt]; 81 82 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 83 [request setEntity:entityDescription]; 84 85 NSPredicate *predicate = [NSPredicate predicateWithFormat: 86 @"date = %@", model.date]; 87 [request setPredicate:predicate]; 88 89 NSError *error = nil; 90 NSArray *listData = [cxt executeFetchRequest:request error:&error]; 91 if ([listData count] > 0) { 92 NoteManagedObject *note = [listData lastObject]; 93 note.content = model.content; 94 95 NSError *savingError = nil; 96 if ([self.managedObjectContext save:&savingError]){ 97 NSLog(@"修改数据成功"); 98 } else { 99 NSLog(@"修改数据失败"); 100 return -1; 101 } 102 } 103 return 0; 104 } 105 106 //查询所有数据方法 107 -(NSMutableArray*) findAll 108 { 109 NSManagedObjectContext *cxt = [self managedObjectContext]; 110 111 NSEntityDescription *entityDescription = [NSEntityDescription 112 entityForName:@"Note" inManagedObjectContext:cxt]; 113 114 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 115 [request setEntity:entityDescription]; 116 117 NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:YES]; 118 [request setSortDescriptors:@[sortDescriptor]]; 119 120 NSError *error = nil; 121 NSArray *listData = [cxt executeFetchRequest:request error:&error]; 122 123 NSMutableArray *resListData = [[NSMutableArray alloc] init]; 124 125 for (NoteManagedObject *mo in listData) { 126 Note *note = [[Note alloc] init]; 127 note.date = mo.date; 128 note.content = mo.content; 129 [resListData addObject:note]; 130 } 131 132 return resListData; 133 } 134 135 //按照主键查询数据方法 136 -(Note*) findById:(Note*)model 137 { 138 NSManagedObjectContext *cxt = [self managedObjectContext]; 139 140 NSEntityDescription *entityDescription = [NSEntityDescription 141 entityForName:@"Note" inManagedObjectContext:cxt]; 142 143 NSFetchRequest *request = [[NSFetchRequest alloc] init]; 144 [request setEntity:entityDescription]; 145 146 NSPredicate *predicate = [NSPredicate predicateWithFormat: 147 @"date = %@",model.date]; 148 [request setPredicate:predicate]; 149 150 NSError *error = nil; 151 NSArray *listData = [cxt executeFetchRequest:request error:&error]; 152 153 if ([listData count] > 0) { 154 NoteManagedObject *mo = [listData lastObject]; 155 156 Note *note = [[Note alloc] init]; 157 note.date = mo.date; 158 note.content = mo.content; 159 160 return note; 161 } 162 return nil; 163 }