四.数据持久化之Core Data

一.可以将oc对象转换成数据保存到sqlite数据库中,也可以将数据库数据还原成oc对象
coredata用的对象结构图如下


四.数据持久化之Core Data_第1张图片
Paste_Image.png

二.实现步骤
第一步 构建模型,并自动创建被管理的实体类。同时构建与之对应的未被管理的实体类
1.构建模型


四.数据持久化之Core Data_第2张图片
Paste_Image.png

2.自动创建被管理的实体类( NSManagedObject对象)
xcode8 按如下方法创建NSManagedObject subclass
四.数据持久化之Core Data_第3张图片
Paste_Image.png

3.构建与之对应的未被管理的实体类

//  Note.h
#import 
@interface Note : NSObject 
@property(nonatomic, strong) NSDate *date;
@property(nonatomic, strong) NSString *content;
- (instancetype)initWithDate:(NSDate *)date content:(NSString *)content;
- (instancetype)init;
@end
//  Note.m
#import "Note.h"

@implementation Note

- (instancetype)initWithDate:(NSDate *)date content:(NSString *)content {
    self = [super init];
    if (self) {
        _date = date;
        _content = content;
    }
    return self;
}

- (instancetype)init {
    self = [super init];
    if (self) {
        _date = [[NSDate alloc] init];
        _content = @"";
    }
    return self;
}

#pragma mark--实现NSCoding协议
- (void)encodeWithCoder:(NSCoder *)aCoder {
    [aCoder encodeObject:_date forKey:@"date"];
    [aCoder encodeObject:_content forKey:@"content"];
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    _date = [aDecoder decodeObjectForKey:@"date"];
    _content = [aDecoder decodeObjectForKey:@"content"];
    return self;
}

@end

第二步:构建持久化操作类(实现上下文,协调器,管理模型三个属性接口,同时实现保存修改接口 saveContext)

//  CoreDataDAO.h ((Data Access Objects) 数据访问对象)
#import 
#import 

@interface CoreDataDAO : NSObject

//被管理的对象上下文
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
//持久化存储协调者
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
//被管理的对象模型
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
//保存数据
- (void)saveContext;

@end
//  CoreDataDAO.m
#import "CoreDataDAO.h"

@interface CoreDataDAO(filePath)
//获得应用程序沙箱Document目录
- (NSURL *)applicationDocumentsDirectory;
@end

@implementation CoreDataDAO(filePath)
//获得应用程序沙箱Document目录
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
@end

@implementation CoreDataDAO

@synthesize managedObjectContext = _managedObjectContext;
@synthesize managedObjectModel = _managedObjectModel;
@synthesize persistentStoreCoordinator = _persistentStoreCoordinator;

#pragma mark - Core Data 堆栈
//返回被管理对象上下文
- (NSManagedObjectContext *)managedObjectContext {

    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    //1.绑定协调器
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

//返回持久化存储协调器
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_persistentStoreCoordinator) {
        return _persistentStoreCoordinator;
    }
    //2.绑定数据库
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreDataNotes.sqlite"];
    //3.和模型绑定
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    NSError *error = nil;
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSLog(@"加载数据失败");
        abort();
    }

    return _persistentStoreCoordinator;
}

//返回被管理对象模型
- (NSManagedObjectModel *)managedObjectModel {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    //4.获得当前工程的bundle
    NSBundle *frameworkBundle = [NSBundle bundleForClass:[CoreDataDAO class]];
    //4.1后缀是momd 不是xcdatamodelid
    NSURL *modelURL = [frameworkBundle URLForResource:@"CoreDataNotes" withExtension:@"momd"];
    //5.绑定模型原件
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

#pragma mark -保存数据
- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        //6.有修改保存
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            NSLog(@"数据保存错误:%@", error.localizedDescription);
            abort();
        }
    }
}

@end

第三步:实现持久化操作类的增删查改

//  NoteDAO.h
#import 
#import "Note.h"
#import "CoreDataDAO.h"

@interface NoteDAO : CoreDataDAO

+ (NoteDAO*)sharedInstance;
//查询所有数据
-(NSMutableArray*) findAll;
//有条件查询
-(Note*) findById:(Note*)model;

//插入Note方法
-(int) create:(Note*)model;
//删除Note方法
-(int) remove:(Note*)model;
//修改Note方法
-(int) modify:(Note*)model;

@end
//  NoteDAO.m
#import 
#import "NoteDAO.h"
#import "NoteManagedObject+CoreDataClass.h"

@interface NoteDAO()
@property (nonatomic,strong) NSDateFormatter *dateFormatter;//日期格式化
@end

@implementation NoteDAO

static NoteDAO *sharedSingleton = nil;

+ (NoteDAO *)sharedInstance {
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        sharedSingleton = [[self alloc] init];
        //初始化DateFormatter
        sharedSingleton.dateFormatter = [[NSDateFormatter alloc] init];
        [sharedSingleton.dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    });
    return sharedSingleton;
}

//查询所有数据
- (NSMutableArray *)findAll
{
    NSMutableArray *result = nil;
    NSManagedObjectContext *cxt = [self managedObjectContext];
    //1.构建fetchRequest (数据提取请求类)
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:cxt];
    //1.1 请求实体
    fetchRequest.entity = entity;

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:TRUE];
    NSArray *sortDescriptors = @[sortDescriptor];
    //1.2 请求排序
    fetchRequest.sortDescriptors = sortDescriptors;

    NSError *error = nil;
    //2.请求返回结果集
    NSArray *listData = [cxt executeFetchRequest:fetchRequest error:&error];
    if (!error) {
        NSMutableArray *resListData = [[NSMutableArray alloc] init];
        //3.获取被管理的实体对象ManagedObject(a.ManagedObject是模型自动创建被管理的类,note是自己创建的未被管理,两者一一对应。b.a.ManagedObject只在数据持久层使用,note也可以在表示层)
        for (NoteManagedObject *mo in listData) {
            Note *note = [[Note alloc] initWithDate:mo.date content:mo.content];
            [resListData addObject:note];
        }
        result = resListData;
    }
    return result;
}

//有条件查询(按照主键查询数据方法)
- (Note *)findById:(Note *)model
{
    Note * result = nil;
    NSManagedObjectContext *cxt = [self managedObjectContext];

    //1.构建fetchRequest (数据提取请求类)
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:cxt];
    //1.1实体
    fetchRequest.entity = entity;
    //1.2 设置查询条件
    fetchRequest.predicate = [NSPredicate predicateWithFormat: @"date = %@",model.date];

    NSError *error = nil;
    //2.请求返回结果集
    NSArray *listData = [cxt executeFetchRequest:fetchRequest error:&error];
    //3.获取被管理的实体对象ManagedObject,建立与之对应的未被管理的实体类
    if (error == nil && [listData count] > 0) {
        NoteManagedObject *mo = [listData lastObject];
        Note *note = [[Note alloc] initWithDate:mo.date content:mo.content];
        result = note;
    }
    return result;
}

//插入Note方法
- (int)create:(Note *)model
{
    NSManagedObjectContext *cxt = [self managedObjectContext];
    //1.创建一个被管理的note对象
    NoteManagedObject *note = [NSEntityDescription insertNewObjectForEntityForName:@"Note" inManagedObjectContext:cxt];
    note.date = model.date;
    //1.1或者用如下方法设置
//    [note setValue:model.date forKey:@"date"];
    note.content = model.content;

    //2.保存数据,同步到持久化数据文件中
    [self saveContext];

    return 0;
}

//删除Note方法
- (int)remove:(Note *)model
{
    NSManagedObjectContext *cxt = [self managedObjectContext];

    //1.构建fetchRequest (数据提取请求类)
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:cxt];
    //1.1实体
    [request setEntity:entityDescription];
    //1.2 设置删除条件
    request.predicate = [NSPredicate predicateWithFormat: @"date = %@", model.date];

    NSError *error = nil;
    //2.查出要删除的实体(所以和查询很像),再删除
    NSArray *listData = [cxt executeFetchRequest:request error:&error];

    if (error == nil && [listData count] > 0) {
        NoteManagedObject *note = [listData lastObject];
        //3.删除
        [self.managedObjectContext deleteObject:note];
        //4.保存修改数据
        [self saveContext];
    }

    return 0;
}

//修改Note方法
- (int)modify:(Note *)model {

    NSManagedObjectContext *cxt = [self managedObjectContext];

    //1.构建fetchRequest (数据提取请求类)
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Note" inManagedObjectContext:cxt];
    //1.1实体
    [request setEntity:entityDescription];

    //1.2 设置修改条件
    NSPredicate *predicate = [NSPredicate predicateWithFormat: @"date = %@", model.date];
    [request setPredicate:predicate];

    NSError *error = nil;
    //2.查出要修改的实体(所以和查询很像),再修改
    NSArray *listData = [cxt executeFetchRequest:request error:&error];

    if (error == nil && [listData count] > 0) {
        //3.修改
        NoteManagedObject *note = [listData lastObject];
        note.content = model.content;
        //4.保存修改数据
        [self saveContext];
    }
    return 0;
}

@end

ps:coreData绑定的数据库存在如下文件里面(需要第三方工具查看)


四.数据持久化之Core Data_第4张图片
Paste_Image.png

如果你发现本文对你有所帮助,如果你认为其他人也可能受益,请把它分享出去。

你可能感兴趣的:(四.数据持久化之Core Data)