zoukankan      html  css  js  c++  java
  • iOS数据存储之CoreData

    iOS中大量数据的储存一个是SqLite,另一个就是CoreData,CoreData允许程序员以面向对象的思维方式的方法去操作面向表的数据库

    做过Java开发的对这个应该很熟悉,Java中的Hibernate跟CoreData就很相似

    CoreData应该怎样使用呢?

    第一步,新建工程后导入CoreData框架

    第二部,创建CoreData的数据模型创建步骤如下

    然后给你的model起个名字,创建完成后你会看到一个这个文件(相当于数据库文件)

    点击这个文件,然后看下图

    点击图中1,新建实体(类似于数据局库中的表),,,然后再图中2位置给你的实体命名,,然后再图中三位置,给你的实体添加字段(类似于数据库中的列名)

    前面只是建立了数据库里面的表,要通过类对象操作表,还需要有与之对应的对象

    接下来就创建与之对应的对象,创建CoreData对象跟平常我们自己创建NSObject对象不同,CoreData对象是由工具创建的;见下图

    按照图中的方式,一路next,之后你会发现,你的目录树中对了两个文件,名字与你的实体名相同

    至此就完成了使用CoreData的基本工具上的工作,下面我们就开始写代码了

    要在代码里跟操作CoreData文件,需要一个上下文对象(类似于sql中的句柄)

    NSManagedObjectContext *sharedContext;

    我们刚才创建哪些CoreData用的文件时,程序运行,APP会在MainBundle里创建一些文件,而这些文件就对应着创建的模型

    ,要操作一个或多个模型,需要用代码把这些文件合并起来,下面是合并的代码

    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];

    然后数据文件表和对象建立关系需要一个中心调度者,

    中心调度这可以建立起数据库和对象以及模型文件之间的对应关系

    对应代码如下

     NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];
        [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:path] options:nil error:nil];
        
        _sharedContext = [[NSManagedObjectContext alloc] init];
        _sharedContext.persistentStoreCoordinator = coordinator;

    到此为止我们就可以很HAPPy的使用上下文操作对象和数据库之间的关系了

    首先来看怎么向数据库中插入一个对象数据

    因为要使对象跟数据库建立存储关系,所以创建对象时不要用以前的alloc 和init来创建了

    要使用工具提供的方法,这样系统才知道对象和数据库的联系

    Person *per = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:[DataManager sharedDataManager].sharedContext];
        per.name = @"jing";
        per.phoneNo = @"123123123";
        
        if([_sharedContext save:nil]){
            NSLog(@"yes");
        }else{
            NSLog(@"no");
        }

    这样就可以将per对象存入到数据库中

    下面就看看怎么去取数据

    CoreData里取数据是就是去数据库里面查询数据,然后将数据返回来,因此我们需要一个查询结果控制器(非视图控制器)

    NSFetchedResultsController *_fetchedResultsController;

    执行查询的代码如下

    // 查询请求
        NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
        
        // 按照用户姓名升序排序
        NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
        
        request.sortDescriptors = @[sort];
        
        /**
         参数:
         1> 查询请求
         2> 数据库上下文
         3> 表格中用于分组的字段名
         4> 缓存名称
         */
        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
        
        // 设置代理
        _fetchedResultsController.delegate = self;
        
        // 执行请求,抓取数据
        NSError *error = nil;
        
        if ([_fetchedResultsController performFetch:&error]) {
            NSLog(@"查询成功");
            
            NSLog(@"%@", _fetchedResultsController.sections);
            
        } else {
            NSLog(@"查询失败 %@", error.localizedDescription);
        }

    创建查询结果控制器需要一个查询请求(类似于web请求中的URLrequest)和要查询的上下文

    查询请求中需要写上查询model的名字,并且还需要给其设置一个排序的规则NSSortDescriptor对象(可以设置多个字段排序)

    创建查询结果控制器的时候sectionNameKeyPath,有兴趣的可以研究一下,这个可以用来将查询后的数据分组(传入nil意味着所有的数据都在一组里)

    上面的代码只是让查询结果控制器去数据库里面查找,如何将数据从结果控制器里面取出来呢?

    Person *person = [_fetchedResultsController objectAtIndexPath:indexPath];

    上面的代码可以将查询结果取出来,看着是不是很眼熟,跟TableView的一些方法是不是很像~,你在看看下面的代码

    int total =  [_fetchedResultsController.sections[0] numberOfObjects];

    上面的代码可以返回第0组数据中所含有的数据总数,是不是觉得跟tableview更像了

    查询到这就完了,下面在看看如何删除一个对象

    // 让上下文删除
            [context deleteObject:person];
            
            // 上下文保存
            if ([context save:nil]) {
                NSLog(@"删除成功!");
            } else {
                NSLog(@"删除失败!");
            }

    上面一句话就搞定~怎么修改对象呢?

    per.name = @"wokao";
      if ([context save:nil]) {
            NSLog(@"保存成功");
            
            // 返回上级视图控制器
            [self.navigationController popViewControllerAnimated:YES];
        } else {
            NSLog(@"保存失败!");
        }

    直接在对象上修改你要修改的,然后save就行了,~╮(╯▽╰)╭是不是木有压力呢?

    还有一个问题就是查询到了很多结果,怎么才能筛选一下呢>?你查到了100个结果,但是只有10个是你像看到的,怎么办呢?

    表着急~有办法~

     // 1. 获取到查询结果控制器中的查询请求
        NSFetchRequest *reqest = _fetchedResultsController.fetchRequest;
        
        if (searchText.length > 0) {
            // 设置请求的过滤谓词
            reqest.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@", searchText];
        } else {
            reqest.predicate = nil;
        }
        
        // 执行查询
        if ([_fetchedResultsController performFetch:nil]) {
            NSLog(@"刷新成功");
            [self.tableView reloadData];
        }

    其实筛选就是把当时给查询结果控制器的请求在拿出来,加点谓词进去~然后重新执行查询就行了~

    如果想恢复到原来的查询结果,request.predicate = nil;然后再重新查询就行了~

    jiandannnnnnnn   ba 

    另外CoreData可以很轻松的存储二进制数据,如果你想用sql存储二进制数据啥的估计要费点劲了,而写很有可能或拖累你的查询性能

    下面一行代码可以将UIImage对象转换为NSData对象

    UIImagePNGRepresentation(_iconButton.imageView.image);

    以后你会用的找的~~~~~~

    还有一个照片选择控制器

    UIImagePickerController

    至于怎么用,自己去查资料~

  • 相关阅读:
    CentOS7 Failed to start LSB: Bring up/down解决方法
    【转】Java包管理器Maven学习
    Android开发-API指南-<category>
    Android开发-API指南-<application>
    Android开发-API指南-<activity-alias>
    Android开发-API指南-<activity>
    Android开发-API指南-<action>
    Android开发-API指南-Android简介
    Android开发-API指南-Activity
    Android开发-API指南-应用程序开发基础
  • 原文地址:https://www.cnblogs.com/xyzaijing/p/3864250.html
Copyright © 2011-2022 走看看