IOS---数据持久化(Core Data)

  • Core Data不是数据库,⽽而是使⽤用数据库、XML、二进制⽂文件等⽅方式来存储数据的⼀个框架。

  • Core Data是iOS3之后才出现的一个框架,允许我们以面向对象的⽅式储存和管理数据。使⽤Core Data框架,我们可以很轻松有效地通过面向对象的接⼝管理数据。

  • Core Data框架提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,

  • 保存在SQLite3数据库文件中,也能够将保存在数据库中的数据还原成OC对象。 在数据操作过程中,⽆需编写任何SQL语句。

##1、CoreData核心对象:

  • NSManagedObject:模型对象,或者叫实体(entity),可理解为OC⾥里的对象。
  • NSManagedObjectModel:模型文件(.xcdatamodeld),记录所有的模型对象及对象 的属性
  • NSPersistentStoreCoordinator:持久化存储协调者,是数据库和程序之间的桥梁, ⽤来设置数据存储的名字,位置,存储⽅式,和存储时机。用来执⾏行具体的CRUD操作。
  • NSManagedObjectContext:对象管理上下文,⽤户所有的持久化操作都是通过此对象。再由此对象去调用NSPersistentStoreCoordinator对象执⾏具体的操作。

##2、基于SQLite数据库时,Core Data的简单使用

和SQLite的区别:只能取出整个实体记录,然后分解,之后才能得到实体的某个属性

构建流程

1.若是新建的工程,选择空白应用程序,next

2.勾选Use Core Data选项

此时生成的工程文件AppDelegate中,会自动生成被管理的数据上下文等相关代码

被管理的数据上下文 初始化的后,必须设置持久化存储助理

- (NSManagedObjectContext *)managedObjectContext {
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }
    
    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (!coordinator) {
        return nil;
    }
    _managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
    [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    return _managedObjectContext;
}

被管理的数据模型 初始化必须依赖.momd文件路径,而.momd文件由.xcdatamodeld文件编译而来

- (NSManagedObjectModel *)managedObjectModel {
    
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"CoreData" withExtension:@"momd"];
    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
    return _managedObjectModel;
}

持久化存储助理 初始化必须依赖NSManagedObjectModel,之后要指定持久化存储的数据类型,默认的是NSSQLiteStoreType,即SQLite数据库;并指定存储路径为Documents目录下,以及数据库名称

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"CoreData.sqlite"];
    NSError *error = nil;
    
    NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption:@YES,NSInferMappingModelAutomaticallyOption:@YES};
    NSString *failureReason = @"There was an error creating or loading the application's saved data.";
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data";
        dict[NSLocalizedFailureReasonErrorKey] = failureReason;
        dict[NSUnderlyingErrorKey] = error;
        error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict];
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
    
    return _persistentStoreCoordinator;
}

方法saveContext表示:保存数据到持久层(数据库)

- (void)saveContext {
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
    if (managedObjectContext != nil) {
        NSError *error = nil;
        if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) {
            
            NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            abort();
        }
    }
}

方法applicationDocumentsDirectory表示:应用程序沙箱下的Documents目录路径

- (NSURL *)applicationDocumentsDirectory {
    
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}

3.如果不是新工程,也可以自己写入相关代码(创建一个新的工程复制过来也行)

###2.1添加数据

获得AppDelegate的代理对象

AppDelegate *delegate = [UIApplication sharedApplication].delegate;

添加实体对象

// 创建实体对象
    // NSEntityDescription *entity = [NSEntityDescription entityForName:@"User" inManagedObjectContext:delegate.managedObjectContext];
    
    //添加一个实体对象到 managedObjectContext 中
    User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:delegate.managedObjectContext];
    user.userID = @10002;
    user.userName = @"怀化";
    user.userAge = @30;
    user.userSex = @"男";
    user.userDate = [NSDate date];

保存上下文:

[delegate saveContext];

###2.2查询数据

创建一个取值请求:

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];

使用谓词设置查询条件:

request.predicate = [NSPredicate predicateWithFormat:@"userAge < 35"];
request.predicate = [NSPredicate predicateWithFormat:@"userName LIKE '*杨*'"];

设置查询的条数:

request.fetchLimit = 2;

指定从某个位置开始查询(分页效果)

request.fetchOffset = 2;

按某个字段升序、降序排列(YES为升序,NO为降序)

NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"userAge" ascending:YES];
    request.sortDescriptors = @[sort];

在上下文中执行取值请求:

NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:&error];
    
    [objects enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        User *user = (User *)obj;
        
        NSLog(@"%@ %@ %@ %@ %@",user.userID, user.userName, user.userAge, user.userSex, user.userDate);
    }];

###2.3 修改数据数据

查询:

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    request.predicate = [NSPredicate predicateWithFormat:@"userID == '10005'"];
    
    NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:nil];

修改:

    
   [objects enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
   	User *user = (User *)obj;
   user.userDate = [NSDate date];
    //保存
   	[delegate saveContext];
}   	

###2.3删除数据

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"User"];
    request.predicate = [NSPredicate predicateWithFormat:@"userID == '10005'"];
    
    NSArray *objects = [delegate.managedObjectContext executeFetchRequest:request error:nil];
    
    [objects enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        
        // 2、删除
        [delegate.managedObjectContext deleteObject:obj];
        
        // 3、保存
        [delegate saveContext];
    }];

##3、数据库依赖关系

在存在数据的过程中,可能会遇到一些相互之间有关联的数据,比如一个学生有很多本书,每本书的属性不同

在模型文件中,设置Relationships关系就可以添加关联关系

  • 设置关联关系的Type为To Many就是一对多的关系,To One则为一对一

  • 设置关联关系的 delete rule 为 cascade 时,当删除当前数据时所关联的数据也会被删除。如果为 Nullify(默认) 就不会删除关联的数据

有时在操作数据比较大的情况下,在当前线程执行会造成软件卡顿的情况,这时可以运用下列方法。

多线程下执行:

   [[CoreDataManager shareManager].moContext performBlock:^{
        
        [stus enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
            Student *stu = (Student *)obj;
            
            NSLog(@"%@ %@ %@ %@ %@",stu.stuID,stu.stuName,stu.stuAge,stu.book.bookName, stu.apples);
            
            [stu.apples enumerateObjectsUsingBlock:^(Apples * _Nonnull obj, BOOL * _Nonnull stop) {
                
                Apples *apple = (Apples *)obj;
                NSLog(@"%@ %@",apple.appleName, apple.applePrice);
            }];
        }];
        
    }];
}

##4、第三方框架(MagicalRecord)使用更简单方便快捷

下载地址:https://github.com/fuxinto/MagicalRecord

Demo下载地址:

https://github.com/fuxinto/HfxDemo

转载于:https://my.oschina.net/6603044/blog/741714

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值