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
至于怎么用,自己去查资料~
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。