iOS 数据持久化 CoreData

          CoreData是iOS3.0后引入的数据持久化解决方案, 是一种对象关系映射(ORM), 例如Java后台中的hibernate, iOS中ORM框架首先CoreData, 这是官方推荐的 不需要借助第三方框架,实际上是对sqlite的封装,提供了更高级的持久化方式, 在数据库操作时, 不需要使用sql语句, 也可以直接操作数据库

          ORM框架的作用:将关系数据库中的表(实体)转换成程序中的对象, 其本质还是对数据库的操作, CoreData将对象关系的映射简化了

           使用CoreData进行数据库存取并不需要手动创建数据库, 这个过程完全有CoreData框架完成, 开发人员面对的是模型, 主要的工作就是把模型创建起来, 具体的数据库如何创建也不用管,

            CoreData与SQLite相比较, SQLite比较原始, 操作比较复杂, 使用的是C的函数对数据库进行的操作, 但是CoreData不能跨平台, SQLite能够跨平台, 可控性更强, 更加轻量级.


下面简单的学习下CoreData的使用:


1. 创建工程的时候要勾选 user CoreData





2. 在Appdelegate中会自动生成以下对象和方法



iOS 数据持久化 CoreData_第1张图片


iOS 数据持久化 CoreData_第2张图片


其中 各个对象的作用:(NSManagerObjectContext 比较重要)


  • Persistent Object Store:可以理解为存储持久对象的数据库(例如SQLite,注意Core Data也支持其他类型的数据存储,例如xml、二进制数据等)。

  • Managed Object Model:对象模型,对应Xcode中创建的模型文件。

  • Persistent Store Coordinator:对象模型和实体类之间的转换协调器,用于管理不同存储对象的上下文。

  • Managed Object Context:对象管理上下文,负责实体对象和数据库之间的交互。


3. 创建实体模型和关系:


iOS 数据持久化 CoreData_第3张图片iOS 数据持久化 CoreData_第4张图片


模型创建的过程中注意:


  • 实体对象不需要创建ID主键,Attributes中应该是有意义属性(创建过程中应该考虑对象的属性而不是数据库中表有几个字段,尽管多数属性会对应表的字段)。

  • 所有的属性应该指定具体类型(尽管在SQLite中可以不指定),因为实体对象会对应生成ObjC模型类。

  • 实体对象中其他实体对象类型的属性应该通过Relationships建立,并且注意实体之间的对应关系(例如一个用户有多条微博,而一条微博则只属于一个用户,用户和微博形成一对多的关系)。


4. 根据上面的模型文件(.xcdatamodeld文件)生成具体的实体类.


iOS 数据持久化 CoreData_第5张图片


每个实体类系统自动生成了4个文件User.h, User.m (User的CoreDataProperties的类目)



iOS 数据持久化 CoreData_第6张图片


需要注意的是以下几点:


  • 所有的实体类型都继承于NSManagedObject,每个NSManagedObject对象对应着数据库中一条记录。

  • 集合属性(例如User中的status)生成了访问此属性的分类方法。

  • 使用@dynamic代表具体属性实现,具体实现细节不需要开发人员关心。

5. 创建好实体和关系, 就可以对数据进行增删改查的操作了:


CoreData的增删改查的操作主要是基于NSManagerObjectContext, 创建上下文, 保存数据

这里可以使用Appdelegate提供的NSManagerObjectContext这个对象

增加数据: 需要调用NSEntityDescription返回一个实体对象, 然后设置对象的属性, 保存上下文(进行增删改操作的时候, 一定要调用管理上下文的保存方法, 否则操作不会执行)


[objc] view plain copy print?

  1. <span style="font-size:18px;">// 添加数据  

  2. - (IBAction)add:(id)sender {  

  3.     // 用NSEntityDescription创建实体对象  

  4.     User *user = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:self.managerObjectContext];  

  5.     user.name = @"Xia";  

  6.     user.age = @"18";  

  7.     user.time = [NSDate dateWithTimeIntervalSinceNow:0];  

  8.     NSError *error;  

  9.     // 保存上下文  

  10.     if (![self.managerObjectContext save:&error]) {  

  11.         NSLog(@"添加过程中的错误信息---%@", error.localizedDescription);  

  12.     }  

  13. }</span>  


查询数据: 通过谓词来实现的, 首先创建一个请求, 设置请求的谓词, 调用上下文执行


注意: 下面有关于NSPredicate拓展


[objc] view plain copy print?

  1. <span style="font-size:18px;">// 查询数据  

  2. - (IBAction)equery:(id)sender {  

  3.     // 查询获取请求, 设置查询哪个实体 EntityName  

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

  5.     // NSFetchRequest 有个属性 谓词 predicate(NSPredicate类型)  

  6.     // 类似于查询语句的查询条件   用来条件查询  

  7.       

  8.     // 查询 user表中 name是Xia的User  

  9.     request.predicate = [NSPredicate predicateWithFormat:@"name='Xia'"];  

  10.       

  11.     // 也可以使用下面的查询语句格式  

  12. //    NSString *name = @"Xia";  

  13. //    request.predicate = [NSPredicate predicateWithFormat:@"name like [cd] %@", name];  

  14.     NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];  

  15. }</span>  


删除数据


[objc] view plain copy print?

  1. <span style="font-size:18px;">// 删除数据  

  2. - (IBAction)delete:(id)sender {  

  3.       

  4.     // 先获取表里的所有数据  

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

  6.     NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];  

  7.       

  8.     // 对表里数据的数组进行遍历  

  9.     for (User *user in array) {  

  10.         // 条件删除  

  11.         if ([user.name isEqualToString:@"Xia"]) {  

  12.             [self.managerObjectContext deleteObject:user];  

  13.         }  

  14.           

  15.     }  

  16.       

  17.     NSError *error;  

  18.     // 保存上下文  

  19.     if (![self.managerObjectContext save:&error]) {  

  20.         NSLog(@"删除过程中发生的错误信息 ----- %@", error.localizedDescription);  

  21.     }  

  22. }</span>  



更新数据



[objc] view plain copy print?

  1. <span style="font-size:18px;">// 更新数据  

  2. - (IBAction)update:(id)sender {  

  3.     // 先获取某个实体  

  4.     User *user = [self getUserByUserName:@"Xia"];  

  5.       

  6.     // 修改实体的属性  

  7.     user.name = @"Yan";  

  8.     user.age = @"20";  

  9.       

  10.     NSError *error;  

  11.     // 保存上下文  

  12.     if (![self.managerObjectContext save:&error]) {  

  13.         NSLog(@"更新数据发生错误 错误信息----%@", error.localizedDescription);  

  14.     }  

  15. }  

  16.   

  17.   

  18. // 通过username 获取 User实体类  

  19. - (User *)getUserByUserName:(NSString *)username  

  20. {  

  21.     // User *user = [[User alloc] init];  

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

  23.     NSArray *array = [self.managerObjectContext executeFetchRequest:request error:nil];  

  24.     for (User *auser in array) {  

  25.         if ([auser.name isEqualToString:username]) {  

  26.             return auser;  

  27.          

  28.         }  

  29.     }  

  30.     return nil;  

  31. }</span>  


 关于NSPreidicate的拓展

    NSPredicate用于查询和过滤
    在SQL中作为查询条件通常用WHERE,但在COREDATA中作为查询条件就可以用到NSPredicate.
    NSPredicate 不单可以和COREDATA中的FetchRequest 配合使用。也可以与NSArray配合使用。
    NSPredicate 中支持的关键词和条件符:
    

    1、>,<,>=,<=,= 比较运算符。

    
    如:
    
    NSPredicate * qcondition= [NSPredicate predicateWithFormat:@"salary >= 10000"];

    2、字符串操作(包含):BEGINSWITH、ENDSWITH、CONTAINS

    
    如:
    
    @"employee.name BEGINSWITH[cd] '李'" //姓李的员工
    
    @"employee.name ENDSWITH[c] '梦'"   //以梦结束的员工
    
    @"employee.name CONTAINS[d] '宗'"   //包含有"宗"字的员工
    
    注:[c]不区分大小写[d]不区分发音符号即没有重音符号[cd]既不区分大小写,也不区分发音符号。
    
    
    

    3、范围:IN   ,BWTEEN

    
    如:
    
    @"salary BWTEEN {5000,10000}"
    
    @"em_dept IN '开发'"
    
    
    

    4、自身:SELF,这个只针对字符数组起作用。

    
    如:
    
    NSArray * test = =[NSArray arrayWithObjects: @"guangzhou", @"beijing", @"shanghai", nil];
    
    @"SELF='beijing'"
    
    
    

    5、通配符:LIKE

    
    LIKE 使用?表示一个字符,*表示多个字符,也可以与c、d 连用。
    
    如:
    
    @"car.name LIKE '?he?'" //四个字符中,中间为he
    
    @"car.name LIKE '*jp'"   //以jp结束
    
    

    6、正则表达式:MATCHES

    
    如:
    
    NSString *regex = @"^E.+e$";//以E 开头,以e 结尾的字符。
    NSPredicate *pre= [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
    if([pre evaluateWithObject: @"Employee"]){
        NSLog(@"matches YES");
        
    }else{
        NSLog(@"matches NO");
        
    }
    

    7、逻辑运算符:AND、OR、NOT

    如:
    
    @"employee.name = 'john' AND employee.age = 28"
    

    8、占位符:

    NSPredicate *preTemplate = [NSPredicate predicateWithFormat:@"name==$NAME"];
    NSDictionary *dic=[NSDictionary dictionaryWithObjectsAndKeys:
                       @"Name1", @"NAME",nil];
    NSPredicate *pre=[preTemplate predicateWithSubstitutionVariables: dic];
    占位符就是字典对象里的key,因此你可以有多个占位符,只要key 不一样就可以了。




CoreData的操作会转换为SQL操作, 在Xcode上设置支持CoreData调试

Product-Scheme-Edit Scheme-Run-Arguments中依次添加两个参数(注意参数顺序不能错):-com.apple.CoreData.SQLDebug1。然后在运行程序过程中如果操作了数据库就会将SQL语句打印在输出面板


iOS 数据持久化 CoreData_第7张图片


你可能感兴趣的:(ios,coredata)