CoreData 使用

末鹿安然 提交于 2020-03-06 13:37:05


一、CoreData的简单使用

准备工作

  • 创建数据库

  1. 新建文件,选择CoreData -> DataModel

  2. 添加实体(表),Add Entity

  3. 给表中添加属性,点击Attributes下方的‘+’

  • 创建模型文件

    1. 新建文件,选择CoreData -> NSManaged Object subclass

    2. 根据提示,选择实体

  • 通过代码,关联数据库和实体

    - (void)viewDidLoad {
       [super viewDidLoad];   /*
        * 关联的时候,如果本地没有数据库文件,Coreadata自己会创建
        */
    
       // 1. 上下文
       NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];   // 2. 上下文关连数据库
    
       // 2.1 model模型文件
       NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];   // 2.2 持久化存储调度器
       // 持久化,把数据保存到一个文件,而不是内存
       NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];   // 2.3 设置CoreData数据库的名字和路径
       NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];   NSString *sqlitePath = [doc stringByAppendingPathComponent:@"company.sqlite"];
    
       [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:nil];
    
       context.persistentStoreCoordinator = store;
       _context = context;
    
    }
  • CoreData的基本操作(CURD)

    • 添加元素 - Create

      -(IBAction)addEmployee{   // 创建一个员工对象 
         //Employee *emp = [[Employee alloc] init]; 不能用此方法创建
         Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:_context];
         emp.name = @"wangwu";
         emp.height = @1.80;
         emp.birthday = [NSDate date];   // 直接保存数据库
         NSError *error = nil;
         [_context save:&error];   if (error) {       NSLog(@"%@",error);
         }
      }
    • 读取数据 - Read

        -(IBAction)readEmployee{      // 1.FetchRequest 获取请求对象
            NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];      // 2.设置过滤条件
            // 查找zhangsan
            NSPredicate *pre = [NSPredicate predicateWithFormat:@"name = %@",                          @"zhangsan"];
            request.predicate = pre;      // 3.设置排序
            // 身高的升序排序
            NSSortDescriptor *heigtSort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:NO];
            request.sortDescriptors = @[heigtSort];      // 4.执行请求
            NSError *error = nil;      NSArray *emps = [_context executeFetchRequest:request error:&error];      if (error) {          NSLog(@"error");
            }      //NSLog(@"%@",emps);
            //遍历员工
            for (Employee *emp in emps) {          NSLog(@"名字 %@ 身高 %@ 生日 %@",emp.name,emp.height,emp.birthday);
            }
        }
    • 修改数据 - Update

      -(IBAction)updateEmployee{   // 改变zhangsan的身高为2m
      
         // 1.查找到zhangsan
         // 1.1FectchRequest 抓取请求对象
         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];   // 1.2设置过滤条件
         // 查找zhangsan
         NSPredicate *pre = [NSPredicate predicateWithFormat:@"name = %@", @"zhangsan"];
         request.predicate = pre;   // 1.3执行请求
         NSArray *emps = [_context executeFetchRequest:request error:nil];   // 2.更新身高
         for (Employee *e in emps) {
             e.height = @2.0;
         }   // 3.保存
         NSError *error = nil;
         [_context save:&error];   if (error) {       NSLog(@"%@",error);
         }
      }
    • 删除数据 - Delete

      -(IBAction)deleteEmployee{   // 删除 lisi
      
         // 1.查找lisi
         // 1.1FectchRequest 抓取请求对象
         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];   // 1.2设置过滤条件
         // 查找zhangsan
         NSPredicate *pre = [NSPredicate predicateWithFormat:@"name = %@",                       @"lisi"];
         request.predicate = pre;   // 1.3执行请求
         NSArray *emps = [_context executeFetchRequest:request error:nil];   // 2.删除
         for (Employee *e in emps) {
             [_context deleteObject:e];
         }   // 3.保存
         NSError *error = nil;
         [_context save:&error];   if (error) {       NSLog(@"%@",error);
         }
      
      }

    二、CoreData的表关联

    准备工作

    • 创建数据库

    1. 新建文件,选择CoreData -> DataModel

    2. 添加实体(表),Add Entity , 注意:这里根据关联添加多个实体

    3. 给表中添加属性,点击Attributes下方的‘+’

  • 创建模型文件

    1. 新建文件,选择CoreData -> NSManaged Object subclass

    2. 根据提示,选择实体,注意:这里先选择被关联的实体,最后添加最上层的实体

  • 通过代码,关联数据库和实体

    - (void)viewDidLoad {
       [super viewDidLoad];   /*
        * 关联的时候,如果本地没有数据库文件,Coreadata自己会创建
        */
    
       // 1. 上下文
       NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];   // 2. 上下文关连数据库
    
       // 2.1 model模型文件
       NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];   // 2.2 持久化存储调度器
       // 持久化,把数据保存到一个文件,而不是内存
       NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];   // 2.3 设置CoreData数据库的名字和路径
       NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];   NSString *sqlitePath = [doc stringByAppendingPathComponent:@"company.sqlite"];
    
       [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:nil];
    
       context.persistentStoreCoordinator = store;
       _context = context;
    
    }
  • 基本操作

    • 添加元素 - Create

      -(IBAction)addEmployee{   // 1. 创建两个部门 ios android
         //1.1 iOS部门
         Department *iosDepart = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:_context];
         iosDepart.name = @"ios";
         iosDepart.departNo = @"0001";
         iosDepart.createDate = [NSDate date];   //1.2 Android部门
         Department *andrDepart = [NSEntityDescription insertNewObjectForEntityForName:@"Department" inManagedObjectContext:_context];
         andrDepart.name = @"android";
         andrDepart.departNo = @"0002";
         andrDepart.createDate = [NSDate date];   //2. 创建两个员工对象 zhangsan属于ios部门 lisi属于android部门
         //2.1 zhangsan
         Employee *zhangsan = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:_context];
         zhangsan.name = @"zhangsan";
         zhangsan.height = @(1.90);
         zhangsan.birthday = [NSDate date];
         zhangsan.depart = iosDepart;   //2.2 lisi
         Employee *lisi = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:_context];
         lisi.name = @"lisi";
         lisi.height = @2.0;
         lisi.birthday = [NSDate date];
         lisi.depart = andrDepart;   //3. 保存数据库
         NSError *error = nil;
         [_context save:&error];   if (error) {       NSLog(@"%@",error);
         }
      }
    • 读取信息 - Read

      -(IBAction)readEmployee{   // 读取ios部门的员工
      
         // 1.FectchRequest 抓取请求对象
         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];   // 2.设置过滤条件
         NSPredicate *pre = [NSPredicate predicateWithFormat:@"depart.name = %@",@"android"];
         request.predicate = pre;     // 4.执行请求
         NSError *error = nil;   NSArray *emps = [_context executeFetchRequest:request error:&error];   if (error) {       NSLog(@"error");
         }   //遍历员工
         for (Employee *emp in emps) {       NSLog(@"名字 %@ 部门 %@",emp.name,emp.depart.name);
         }
      }
    • 其他功能与前几种类似,这里不在赘述

    三、CoreData的模糊查询

    准备工作和上面类似,主要是查询方式不同

    • 模糊查询

      -(IBAction)readEmployee{   // 1.FectchRequest 抓取请求对象
         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];   // 2.设置排序
         // 按照身高的升序排序
         NSSortDescriptor *heigtSort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:NO];
         request.sortDescriptors = @[heigtSort];   // 3.模糊查询
         // 3.1 名字以"wang"开头//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name BEGINSWITH %@",@"wangwu1"];//    request.predicate = pre;
      
         // 名字以"1"结尾//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name ENDSWITH %@",@"1"];//    request.predicate = pre;
      
         // 名字包含"wu1"//    NSPredicate *pre = [NSPredicate predicateWithFormat:@"name CONTAINS %@",@"wu1"];//    request.predicate = pre;
      
         // like 匹配
         NSPredicate *pre = [NSPredicate predicateWithFormat:@"name like %@",@"*wu12"];
         request.predicate = pre;   // 4.执行请求
         NSError *error = nil;   NSArray *emps = [_context executeFetchRequest:request error:&error];   if (error) {       NSLog(@"error");
         }   //遍历员工
         for (Employee *emp in emps) {       NSLog(@"名字 %@ 身高 %@ 生日 %@",emp.name,emp.height,emp.birthday);
         }
      }
    • 分页查询

      -(void)pageSeacher{   // 1. FectchRequest 抓取请求对象
         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Employee"];   // 2. 设置排序
         // 身高的升序排序
         NSSortDescriptor *heigtSort = [NSSortDescriptor sortDescriptorWithKey:@"height" ascending:NO];
         request.sortDescriptors = @[heigtSort];   // 3. 分页查询
         // 总有共有15数据
         // 每次获取6条数据
         // 第一页 0,6
         // 第二页 6,6
         // 第三页 12,6 3条数据
      
         // 3.1 分页的起始索引
         request.fetchOffset = 12;   // 3.2 分页的条数
         request.fetchLimit = 6;   // 4. 执行请求
         NSError *error = nil;   NSArray *emps = [_context executeFetchRequest:request error:&error];   if (error) {       NSLog(@"error");
         }   // 5. 遍历员工
         for (Employee *emp in emps) {       NSLog(@"名字 %@ 身高 %@ 生日 %@",emp.name,emp.height,emp.birthday);
         }
      }

    四、多个数据库的使用

    注意:

    创建多个数据库,即创建多个DataModel
    一个数据库对应一个上下文
    需要根据bundle名创建上下文
    添加或读取信息,需要根据不同的上下文,访问不同的实体

    • 关联数据库和实体

      - (void)viewDidLoad {
         [super viewDidLoad];   // 一个数据库对应一个上下文
         _companyContext = [self setupContextWithModelName:@"Company"];
         _weiboContext = [self setupContextWithModelName:@"Weibo"];
      }        
      
      /**
      *  根据模型文件,返回一个上下文
      */-(NSManagedObjectContext *)setupContextWithModelName:(NSString *)modelName{   // 1. 上下文
         NSManagedObjectContext *context = [[NSManagedObjectContext alloc] init];   // 2. 上下文关连数据库
         // 2.1 model模型文件
      
         // 注意:如果使用下面的方法,如果 bundles为nil 会把bundles里面的所有模型文件的表放在一个数据库
         //NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];
      
         // 改为以下的方法获取:
         NSURL *companyURL = [[NSBundle mainBundle] URLForResource:modelName withExtension:@"momd"];   NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:companyURL];   // 2.2 持久化存储调度器
         // 持久化,把数据保存到一个文件,而不是内存
         NSPersistentStoreCoordinator *store = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];   // 2.3 告诉Coredata数据库的名字和路径
         NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];   NSString *sqliteName = [NSString stringWithFormat:@"%@.sqlite",modelName];   NSString *sqlitePath = [doc stringByAppendingPathComponent:sqliteName];
      
         [store addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:sqlitePath] options:nil error:nil];
      
         context.persistentStoreCoordinator = store;   // 3. 返回上下文
         return context;
      }
    • 添加元素

      -(IBAction)addEmployee{   // 1. 添加员工
         Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" inManagedObjectContext:_companyContext];
         emp.name = @"zhagsan";
         emp.height = @2.3;
         emp.birthday = [NSDate date];   // 直接保存数据库
         [_companyContext save:nil];   // 2. 发微博
         Status *status =[NSEntityDescription insertNewObjectForEntityForName:@"Status" inManagedObjectContext:_weiboContext];
      
         status.text = @"发了一条微博!";
         status.createDate = [NSDate date];
      
         [_weiboContext save:nil];
      }


    易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
    该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!