CoreData与SQLite3
昨天被问到 SQLite3与Core Data有什么区别,当时只是想到了一个是充分利用了传统的SQL语句,另一个是充分利用了面向对象的编程方法,今天早上想了一会,决定以后再有人问我这个问题我就这么回答:
两个方法都可以完成IOS中数据持久化的任务,都是ORM(object-relational
mapping)关系-对象映射的解决方案,SQLIte3本身是一个数据存储的容器,搭配一套方法,单纯滴使用SQLite3类似Java 的MySQL+JDBC,即有一个数据库的实体和一套控制数据库的方法,连接好就可以建立SQL语句,execute就可以了。SQLite3就是这样的,简单粗暴! 另一方面,Core Data是苹果推崇的方法,本身相当于一个库,提供了访问数据类和方法,那么数据存储的另一个要素——存储数据的容器是谁呢?自问自答:可以是二进制文件、xml,而且最重要的其实是SQLite3,不过这倒是没啥大不了的。
跑偏了!在Core Data提供的存储方法中,不再有数据表——>字段的概念,取而代之的实体(Entity)——>属性(Property)这个对应关系,字段中有value,type,取而代之的是Property中的Attributes(特性)中的attribute name,type (我这种分类应该是和别人的分类方法不一样,因为我想突出这里和数据库的对应关系,其实貌似没啥用呵呵)。而且在存储和访问的时候,通过KVC来从数据库中找到实体和特性,而且就是他们的名字!而且xcode中可视化添加实体和属性,类似phpadmin,但是CoreData能够把实体间的relationship直观表示出来。
(补充一句,上面说分类方式有些奇怪,是因为这个Property下面其实还有三个属性:Attributes,relationship,fetch property,由于后两者是关系和操作方面而非不是数据方面的,所以其实要是没有后两者,Attributes是可以作为Entity的直接下级的,Property存在的概念久淡化了)
所以,如果习惯用SQL语句就用SQLite3,如果喜欢用面向对象编程就用CoreData,不过有人说有些任务CoreData不能完成,这个我不清楚了,总之对我现在够用了。
由一个例子入手
1, Managed Object Model
Managed Object Model 是描述应用程序的数据模型,这个模型包含实体(Entity),特性(Property),读取请求(Fetch Request)等。(下文都使用英文术语。)
2,Managed Object Context
Managed Object Context 参与对数据对象(Managed Object)进行各种操作的全过程,并监测数据对象的变化,以提供对 undo/redo 的支持及更新绑定到数据的 UI。
3,Persistent Store Coordinator
Persistent Store Coordinator 相当于数据文件管理器,处理底层的对数据文件的读取与写入。一般我们无需与它打交道。在context的操作下,负责在数据库中生成取出managed object,或者将managed Object存到数据库
4,Managed Object
Managed Object 数据对象,与 Managed Object Context 相关联。
在水果教材上之前的例子中有几处问题没有懂,这个例子是又是贼简单——四个文本框,用户输入啥都行,home时开始存数据到数据库,重新active后读出数据再显示到textField上,说之前我把整段代码都贴上:
1 | // |
其实也没有啥,因为在编程中会用到的其实只有ManagedObjectContext和ManagedObject(哦还有不在这里的NSFetchRequest),下面我就想针对这三个类说一下:
对于小红(知道我说的谁吧)和小绿我想放到一起说,因为她俩是好朋友!看这么一段:1
2
3
4
5
6AppDelegate *appdDelegate = [UIApplication sharedApplication].delegate;
NSManagedObjectContext *context = [appdDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:kLineEntityName];//get table
NSError *error;
NSArray *object = [context executeFetchRequest:request error:&error];
这里再补充点,在之前那篇介绍持久化的博客中,哐哐地把NSManagedObjectContext的定义都写了一遍,其实那个是在工程指定了要用Core Data后在AppDelegate中自动写好啦,前几天比较傻,现在有点豁然开朗的感觉,所以下觉心把这里好好写着。
说上面这段代码,我先把书上的原话码出来 “该方法首先获取对应用委托的引用,我们将使用这个引用获得我们创建的托管对象上下文” -_-#我擦这话组织的无可挑剔,就是完全不懂! 我就理解:有了这两句后,这个context就牛逼了,为啥,因为他承载了APPDelegate中最少三个方法,所谓 “千言万语汇成一个变量”!这之后这个context就可以在本轮数据操作中如入无人之境,因为那三个方法已经把连接数据库,设置App代理完成了,以后就可配合其他参数(如小绿)任意操作数据了。
说完小红,说他的朋友小绿,申请了一个去查询变量,但是,要骑马要指定哪个实体。这里我只想说一个地儿,就是之前看到的声明NSFetchRequest,都跟着一堆,包括指出针对的实体,按照这种init的时候直接指出就好了,当然这里没有加任何谓词,有谓词的话还是要各种set的(比如最大查询条数、大小条件、某时间后等),还是要看本篇的姐妹篇。
哦对了,为啥说小红和小绿是好朋友呢?就是因为这句:
1 | NSArray *object = [context executeFetchRequest:request error:&error]; |
这亲昵程度一目了然。
下面要结合这里说小蓝:1
2
3
4
5NSArray *object = [context executeFetchRequest:request error:&error];
if(object==nil){
NSLog(@"array id empty");
}
for(NSManagedObject *oneObject in object){//get attribute in this table >>>>>>>>>>>>>>>>>2<<<<<<<<<<<<<<<<
这个object,其实是objects,因为这里存了不止一条查询结果。其实这部分我想说的重点是(这里本来想加一个“自认为是重点“来着,反正没人看索性有删掉了(这心理戏是有多足?))这个oneObject, 注意看他的类型——NSManagedObject!即这个变量存储了这个实体的所有attribute,性命、性别、年龄、所选课程组成的一条结果的所有信息都存在这个oneObject中,嗨就是数据库中的一行,取得时候直接用KVC:
NSString *name = [oneObject valueForKey:@”姓名”] ;
int age = [[oneObject valueForKey:@”年龄”] intValue];
1 | if([objects count] > 0){ |
至于这最后一处,就是insert的用法了,不是为了搜索数据。只要得到能控制数据的handler(我想这样称呼),用这个本来就是NSManagedObject实例的theLine变量正合适!按照KVC插入的原则插值就可以了。
貌似这里想说的就是这些,还有就是关于relationship和fetch property的,有机会聊。。。
最后的最后,还是直接把一直说的姊妹篇中说的那三个函数都贴到这里吧:
新建工程,如果选择了Core Data,会在AppDelegate中写好该写的;把Core Data的头文件链接进来;需要的framework也导入,系统自动写的代码如下:
1 | // |
1 | // |
done!