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

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

posted @ 2014-07-23 23:14  784692237  阅读(366)  评论(0编辑  收藏  举报