CoreData的使用
1、使用到的对象
(1)NSManagedObjectContext
操作数据库的上下文(数据库,获取与存储),即负责应用与数据库之间的交互
作用:插入数据、查询数据、删除数据
(2)NSManagedObjectModel
数据库中所有表格和他们的联系(数据模型),即代表CoreData模型文件,相当于实体
作用:添加实体的属性与类型设置,建立属性之间的关系
关联:数据模型地址(NSURL)
(3)NSPersistentStoreCoordinator/NSPersistentStore
数据库存放方式(中介、存储数据),即处理数据存储的链接
作用:设置数据存储的名字、位置、存储方式、存储时机
关联:数据模型(NSManagedObjectModel)、存储位置(NSURL)、存储方式(NSSQLiteStoreType)、存储时机(NSString)、存储迁移(NSDictionary)
(4)NSManagedObject
相当于数据库中的表格的记录(数据对象,管理属性)
(5)NSFetchRequest
相当于查询语句(请求数据,排序/条件/数量)
关联:查询条件(NSPredicate)、查询排序(NSSortDescriptor)、查询数量(NSNumber)
(6)NSEntityDescription(实体结构)
相当于表格结构
注意:后缀为.xcdatamodeld的包,里面是.xcdatamodel文件,用数据模型编辑器编辑,编译后为.momd或.mom文件。
二、实操
(1)创建CoreData的Model。
(2)创建实体,并设置实体中的属性、属性类型。
(3)创建与实体对应的数据对象,以便于管理属性对象。
三、版本升级
当数据库版本升级时,即版本迭代后,数据库中的原实体新增加了属性,或新增加了实体,必须做相应的处理,以避免crash情况。
(1)新增属性,或新增实体后出现异常提示
(2)解决:增加版本号处理。(注意:使用系统默认生成的新版本名称,切忌进行修改)
四、代码
(1)封装类
.h文件 #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @interface CoreDataManager : NSObject /** * 单例模式 * * @return CoreDataManager */ + (CoreDataManager *)shareManager; /** * 创建空的表映射对象 * * @param entityName entityName实体描述名 * * @return id实体类对象 */ -(id)createEmptyObjectWithEntityName:(NSString *)entityName; /** * 查询托管对象上下文中的对象 * * @param predicate predicate查询条件 * @param sortDescriptions sortDescriptions排序条件 * @param entityName entityName实体描述名 * @param limitNum limitNum返回总个数 * * @return NSArray */ - (NSArray *)getListWithPredicate:(NSPredicate*)predicate sortDescriptors:(NSArray *)sortDescriptions entityName:(NSString*)entityName limitNum:(NSNumber *)limitNum; /** * 删除托管对象上下文中的一个对象 * * @param object object需要删除的任意对象 * * @return BOOL */ - (BOOL)deleteObject:(NSManagedObject*)object; /** * 删除托管对象上下文中的一个对象 * * @param object object需要删除的任意对象 * @param complete complete block回调 */ - (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete; /** * 删除托管对象上下文中的所有对象 * * @param entityName entityName实体描述名 * * @return BOOL */ -(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName; /** * 删除托管对象上下文中的所有对象 * * @param entityName entityName实体描述名 * @param complete complete block回调 */ - (void)deleteAllObjectWithEntityName:(NSString*)entityName complete:(void (^)(BOOL isSuccess))complete; /** * 保存托管对象上下文中的更改 * * @return BOOL */ - (BOOL)save; /** * 保存托管对象上下文中的更改 * * @param complete complete block回调 */ - (void)save:(void (^)(BOOLisSuccess))complete; @end
.m文件 #import "CoreDataManager.h" // 数据库名称 static NSString *const CoreDataSQLiteName =@"CoreDataCache.sqlite"; @interface CoreDataManager () @property (nonatomic, strong)NSManagedObjectContext *objectContext; // 托管对象上下文 @end @implementation CoreDataManager /// 数据库存储路径(document) NSString *GetDocumentPathFileName(NSString*lpFileName) { NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES); if (paths && 0 != paths.count) { NSString *documentsDirectory = [paths objectAtIndex:0]; if (documentsDirectory && 0 != documentsDirectory.length) { if (lpFileName && 0 != lpFileName.length) { NSString *filePath =[documentsDirectory stringByAppendingPathComponent:lpFileName]; return filePath; } } } return nil; } - (id)init { self = [super init]; if (self) { if (!self.objectContext) { // 指定存储数据文件(CoreData是建立在SQLite之上的,文件后缀名为:xcdatamodel) NSString *persistentStorePath =GetDocumentPathFileName(CoreDataSQLiteName); NSURL *storeUrl = [NSURL fileURLWithPath:persistentStorePath]; // 数据迁移 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumbernumberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumbernumberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; // 创建托管对象模型 NSURL *modelURL = [[NSBundle mainBundle]URLForResource:@"CacheModel" withExtension:@"momd"]; NSManagedObjectModel *managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:modelURL]; // 创建持久化存储协调器,并使用SQLite数据库做持久化存储 NSPersistentStoreCoordinator *persistentStoreCoordinator =[[NSPersistentStoreCoordinator alloc]initWithManagedObjectModel:managedObjectModel]; NSError *error = nil; NSPersistentStore *persistentStore = [persistentStoreCoordinatoraddPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrloptions:options error:&error]; // 创建托管对象上下文 if (persistentStore && !error) { NSManagedObjectContext*managedObjectContext = [[NSManagedObjectContext alloc] init]; [managedObjectContextsetPersistentStoreCoordinator:persistentStoreCoordinator]; self.objectContext =managedObjectContext; } else { NSLog(@"failed to addpersistent store with type to persistent store coordinator"); NSLog(@"Unresolved error%@, %@", error, [error userInfo]); } } } return self; } + (CoreDataManager *)shareManager { static CoreDataManager *staticCoreDataManager; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ staticCoreDataManager = [[self alloc] init]; assert(staticCoreDataManager != nil); }); return staticCoreDataManager; } -(id)createEmptyObjectWithEntityName:(NSString *)entityName { NSManagedObject *managerObject = [NSEntityDescriptioninsertNewObjectForEntityForName:entityNameinManagedObjectContext:self.objectContext]; return managerObject; } - (NSArray*)getListWithPredicate:(NSPredicate *)predicate sortDescriptors:(NSArray*)sortDescriptions entityName:(NSString *)entityName limitNum:(NSNumber*)limitNum { NSError *error = nil; // 创建取回数据请求 NSFetchRequest *fetchRequest = [NSFetchRequestfetchRequestWithEntityName:entityName]; //设置查询条件 [fetchRequest setPredicate:predicate]; // 设置排序条件 [fetchRequest setSortDescriptors:sortDescriptions]; // 查询条件的总数 [fetchRequest setFetchLimit:[limitNum intValue]]; // 执行获取数据请求,返回数组 NSArray *fetchResult = [self.objectContextexecuteFetchRequest:fetchRequest error:&error]; return fetchResult; } - (BOOL)deleteObject:(NSManagedObject*)object { [self.objectContext deleteObject:object]; BOOL isSuccess = [self save]; return isSuccess; } - (void)deleteObject:(NSManagedObject*)object complete:(void (^)(BOOL isSuccess))complete { BOOL isSuccess = [self deleteObject:object]; if (complete) { complete(isSuccess); } } -(BOOL)deleteAllObjectWithEntityName:(NSString *)entityName { NSArray *allObjects = [self getListWithPredicate:nil sortDescriptors:nilentityName:entityName limitNum:nil]; if (allObjects && 0 != allObjects.count) { for (NSManagedObject *object in allObjects) { [self.objectContext deleteObject:object]; } BOOL isSuccess = [self save]; return isSuccess; } return NO; } -(void)deleteAllObjectWithEntityName:(NSString *)entityName complete:(void(^)(BOOL isSuccess))complete { BOOL isSuccess = [self deleteAllObjectWithEntityName:entityName]; if (complete) { complete(isSuccess); } } - (BOOL)save { NSError *error = nil; BOOL isSuccess = [self.objectContext save:&error]; return isSuccess; } - (void)save:(void (^)(BOOLisSuccess))complete { BOOL isSuccess = [self save]; if (complete) { complete(isSuccess); } } @end
(2)调用封装类
导入头文件
#import "CoreDataManager.h" #import "NameCache.h"
搜索/删除全部/删除指定/保存
- (void)search { NSPredicate *predicate = [NSPredicate predicateWithFormat:@"cacheName== %@", @"zhangshaoyu"]; NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"cacheTime" ascending:NO]; NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil]; NSArray *array = [[CoreDataManager shareManager]getListWithPredicate:predicate sortDescriptors:sortDescriptionsentityName:@"NameCache" limitNum:[NSNumber numberWithInt:10]]; NSLog(@"array %@", array); for (NameCache *cache in array) { NSString *name = cache.cacheName; NSString *key = cache.cacheKey; NSDate *date = cache.cacheTime; NSData *data = cache.cacheImage; NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data); } }
- (void)deleteAll { // // 保存区域信息前先将已有信息删除,避免造成数据重复 // [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache"]; [[CoreDataManager shareManager]deleteAllObjectWithEntityName:@"NameCache" complete:^(BOOL isSuccess){ NSLog(@"%@", [NSStringstringWithFormat:@"delete all:%@", (isSuccess ? @"success": @"failue")]); }]; }
- (void)delete { // 删除某个 NSPredicate *predicate = [NSPredicatepredicateWithFormat:@"cacheName == %@", @"zhangshaoyu"]; NSSortDescriptor*sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"cacheTime"ascending:NO]; NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil]; NSArray *array = [[CoreDataManager shareManager] getListWithPredicate:predicatesortDescriptors:sortDescriptions entityName:@"NameCache"limitNum:[NSNumber numberWithInt:10]]; NSLog(@"array %@", array); for (NameCache *cache in array) { NSString *name = cache.cacheName; NSString *key = cache.cacheKey; NSDate *date = cache.cacheTime; NSData *data = cache.cacheImage; NSLog(@"name = %@, key = %@, date = %@, data = %@", name, key,date, data); // [[CoreDataManager shareManager] deleteObject:cache]; [[CoreDataManager shareManager] deleteObject:cache complete:^(BOOLisSuccess) { NSLog(@"%@", [NSString stringWithFormat:@"deleteobject:%@", (isSuccess ? @"success" : @"failue")]); }]; } }
- (void)save { NSArray *array = [NSArray arrayWithObjects:@"zhangshaoyu",@"herman", @"weishijiajie", nil]; // 保存新信息 for (NSInteger index = 0; index < array.count; index++) { NSString *name = array[index]; NSString *key = [NSString stringWithFormat:@"%ld", index]; NameCache *cache = [[CoreDataManager shareManager]createEmptyObjectWithEntityName:@"NameCache"]; [cache setCacheName:name]; [cache setCacheKey:key]; [cache setCacheTime:[NSDate date]]; NSData *image = [[NSData alloc] initWithContentsOfURL:[NSURLURLWithString:@"http://gtb.baidu.com/HttpService/get?p=dHlwZT1pbWFnZS9qcGVnJm49dmlzJnQ9YWRpbWcmYz10YjppZyZyPTEzMjA2ODYxODAsMzY1MTE3NTc5MgAAAA=="]]; [cache setCacheImage:image]; // [[CoreDataManager shareManager] save]; [[CoreDataManager shareManager] save:^(BOOL isSuccess) { NSLog(@"%@", [NSString stringWithFormat:@"saveobject:%@", (isSuccess ? @"success" : @"failue")]); }]; } }
五、说明
前面所提到的基本上是关于Core Data框架的入门。
Core Data还远不止这些功能,它还支持自动撤销机制,一对多关联等。
待续:自动撤销、关联、数据迁移、数据查看、第三方库使用……。