CoreData的使用
1、使用到的对象
(1)NSManagedObjectContext
操作数据库的上下文(数据库,获取与存储),即负责应用与数据库之间的交互
作用:插入数据、查询数据、删除数据
(2)NSManagedObjectModel
数据库中所有表格和他们的联系(数据模型),即代表CoreData模型文件,相
当于实体
作用:添加实体的属性与类型设置,建立属性之间的关系
关联:数据模型地址(NSURL)、
(3)NSPersistentStoreCoordinator/NSPersistentStore
数据库存放方式(中介、存储数据),即处理数据存储的链接
作用:设置数据存储的名字、位置、存储方式、存储时机
关联:数据模型(NSManagedObjectModel)、存储位置(NSURL)、存储方式(NSSQLiteStoreType)、存储时机(NSString)、存储迁移(NSDictionary)
(4)NSManagedObject
表格的记录(数据对象,管理属性)
(5)NSFetchRequest
查询语句(请求数据,排序/条件/数量)
关联:查询条件(NSPredicate)、查询排序(NSSortDescriptor)、查询数量(NSNumber)
注意:后缀为.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还远不止这些功能,它还支持自动撤销机制,一对多关联等。
待续:自动撤销、关联、数据迁移、数据查看、第三方库使用……。