Coredata第三课 数据查询

问题

小明班上最近月考了,老师大明想要给一部分优秀的同学进行奖励,而另外一部分要进行查漏补缺。大明决定将总分排名前10的,各科成绩排名前10的以及排名最后10名的按从高到低的顺序找出来。以前大明都是在家用笔一个个划出来。不过最近大明在长沙戴维营教育接受了残酷的iOS培训,决定装逼一把,给自己的“肾6+”开发了一款应用。只要各科老师将成绩提交给他,就可以直接看到这些学生的成绩了,并且各种曲线、柱状图、饼图。每个学生的情况就好比没穿衣服一样”透明“。现在的问题是,大明并不想自己去实现各种筛选和排序算法。

解决方法

很快大明就想到了戴维营教育的博客上Core Data除了简单的存取功能外,还具备各种取数据的方法。

一、数据获取

Core Data中获取数据必须通过NSFetchRequest进行。我们有两种方式获取NSFetchRequest对象。

  • 通过实体名称创建NSFetchRequest对象。

这种方式其实就是我们在前面两篇文章中用来获取数据的技巧。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//或者NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];NSEntityDescription *entity = [NSEntityDescription entityForName:@"Person" inManagedObjectContext:context];fetchRequest.entity = entity;
  • 通过模型文件中创建的请求模版创建。

//使用managedModel获取fetchRequest模版NSFetchRequest *fetchRequest = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"personFR"];
  • 我们可以指定fetchRequest的结果类型来获取不同数据,如存储的对象、结果数目等。
//    NSFetchRequest *fetchRequest = [appDelegate.managedObjectModel fetchRequestTemplateForName:@"personFR"];
    //如果需要改变结果的类型,不能使用从模版生成的request对象
    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];
    //获取结果总数
    fetchRequest.resultType = NSCountResultType;

不过我们也不只一种获取结果数目的方式。在Context里面提供了一系列的操作request的方法,其中就包括了获取结果数目的功能。

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//获取结果数目NSUInteger count = [context countForFetchRequest:fetchRequest error:nil];
二、筛选结果集

大明已经可以得到所有学生的成绩信息了,接下来要做的就是对它们进行排序和筛选。

  • 给学生成绩进行排序
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];//排序描述符,按score降序排列NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];//可以同时按多个属性进行排序fetchRequest.sortDescriptors = @[sort01];NSArray *result = [context executeFetchRequest:fetchRequest error:nil];if (result) {
    _people = [NSMutableArray arrayWithArray:result];
    for (NSObject *obj in _people) {
        NSLog(@"%@", [obj valueForKey:@"score"]);
    }}

结果:

2015-02-04 10:54:16.599 02-02-CoreData01[5832:276345] 99
2015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 60
2015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 56
2015-02-04 10:54:16.600 02-02-CoreData01[5832:276345] 45
  • 筛选出成绩排名前十的学生
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];fetchRequest.sortDescriptors = @[sort01];//限制只取前十,其实这是有问题的,万一有重复的分数,后面的就取不到了。fetchRequest.fetchLimit = 10;NSArray *result = [context executeFetchRequest:fetchRequest error:nil];
  • 使用NSPredicate筛选成绩高于90分的学生
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"score >= 90"];fetchRequest.predicate = predicate;

进阶

上面的这些数据获取方式都是同步的方式,如果数据量比较大的话,会显著的影响到程序的性能和用户体验。Core Data中也提供了异步数据获取功能。

AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;NSManagedObjectContext *context = appDelegate.managedObjectContext;NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Person"];NSSortDescriptor *sort01 = [NSSortDescriptor sortDescriptorWithKey:@"score" ascending:NO];fetchRequest.sortDescriptors = @[sort01];fetchRequest.fetchLimit = 2;//异步请求NSAsynchronousFetchRequest *asyncRequst = [[NSAsynchronousFetchRequest alloc] initWithFetchRequest:fetchRequest completionBlock:^(NSAsynchronousFetchResult *result) {
    for (NSObject *obj in result.finalResult) {
        NSLog(@"%@", [obj valueForKey:@"score"]);
    }}];//执行异步请求[context executeRequest:asyncRequst error:nil];

注意: 在使用异步请求的时候,需要设置NSManagedContext对象的并发类型,否则会出错。

2015-02-04 12:12:50.709 02-02-CoreData01[6083:300576] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException‘, reason: ‘NSConfinementConcurrencyType context <NSManagedObjectContext: 0x7fb27b72c5f0> cannot support asynchronous fetch request <NSAsynchronousFetchRequest: 0x7fb27b71d750> with fetch request <NSFetchRequest: 0x7fb27b7247a0> (entity: Person; predicate: ((null)); sortDescriptors: ((    "(score, descending, compare:)")); limit: 2; type: NSManagedObjectResultType; ).‘

解决办法是在创建Context对象的时候,设置它的并发类型。

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];if (!coordinator) {
    return nil;}//创建Context对象,并设置并发类型_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];[_managedObjectContext setPersistentStoreCoordinator:coordinator];

参考资料

  1. Core Data异步操作:http://code.tutsplus.com/tutorials/ios-8-core-data-and-asynchronous-fetching--cms-22241
  2. Core Data并发操作:http://code.tutsplus.com/tutorials/core-data-from-scratch-concurrency--cms-22131
  3. 批量更新Core Data:http://code.tutsplus.com/tutorials/ios-8-core-data-and-batch-updates--cms-22164

本文档由长沙戴维营教育整理。

时间: 2024-10-29 09:09:47

Coredata第三课 数据查询的相关文章

coredata总结三 NSPredicate 条件查询或过虑

NSPredicate用于查询和过滤 在SQL中作为查询条件通常用WHERE,但在COREDATA中作为查询条件就可以用到NSPredicate. NSPredicate 不单可以和COREDATA中的FetchRequest 配合使用.也可以与NSArray配合使用. NSPredicate 中支持的关键词和条件符: 1.>,<,>=,<=,= 比较运算符. 如: NSPredicate * qcondition= [NSPredicate predicateWithFormat

Windows中使用MySQL 数据查询(三)

一.排序 select * from employees order by name; 字符型默认字符顺序(也就是说z永远比a大),不管大小写:如果想按编码值排序(也就是说小写永远大于大写),则使用 select * from employees order by binary name; 二.取前n条记录(n在本例中为3) select * from employees order by id limit 3; 三.日期时间函数 1.获取当前日期 select curdate(); 2.取年

oracle入门之对表数据查询(三)

oracle表复杂查询--子查询 什么是子查询? 子查询是指嵌入在其它sql语句中的select语句,也叫嵌套查询. 单行子查询 单行子查询是指只返回一行数据的子查询语句. 请思考:如果显示与smith同一部门的所有员工? SQL>select * from emp where deptno=(select deptno from emp where ename='SMITH'); 将SMITH排除在外不显示 SQL>select * from emp where deptno=(select

CoreData用法三: NSPredicate在CoreData中的使用

NSPredicate在CoreData中常用作查询使用,相当于sql语句中的where查询子句. 最常用的方法为: NSPredicate *ca = [NSPredicate predicateWithFormat:(NSString *), ...]; 比如我们要查询student表中name="jjy"的信息,我们可以这样去用NSPredicate NSEntityDescription * emEty = [NSEntityDescription entityForName:

3.3 数据查询

第三节  数据查询 (一)格式 select [all|distinct] <目标列表达式>[,<目标列表达式>]... from <表名或视图名>[,<表名或视图名>]... [where<条件表达式>] [group by<列名1>[having <条件表达式>]] [order by<列名2>[asc|desc]] 1.目标列表达式*/表名.*/count(*)/字段名表达式 2.条件表达式 (二)分类介

SQL初级第三课(下)

我们续用第三课(上)的表 辅助表 Student                   Course               Score                    Teacher Sno                         Cno                   Sno                       TnoSname                     Cname               Cno                       Tn

第三课 文件系统(上)

unix_c_03.txt====================第三课 文件系统(上)====================一.系统调用------------应用程序 -----------+| |v |各种库 |(C/C++标准库.Shell命令和脚本. |X11图形程序及库) || |v |系统调用 <----------+(内核提供给外界访问的接口函数,调用这些函数将使进程进入内核态)|v内核(驱动程序.系统功能程序)1. Unix/Linux大部分系统功能是通过系统调用实现的.如o

SharePoint服务器端对象模型 之 使用CAML进展数据查询

SharePoint服务器端对象模型 之 使用CAML进行数据查询 一.概述 在SharePoint的开发应用中,查询是非常常用的一种手段,根据某些筛选.排序条件,获得某个列表或者某一些列表中相应的列表条目的集合. 除去列表上的查询之外,在SharePoint中还大量存在着各种各样的查询,比如针对回收站的SPRecycleBinQuery.针对审计的SPAuditQuery.针对变更的SPChangeQuery等等,不过这些查询在实际项目中使用到的频率并不是很高.本章节还是着重介绍列表查询功能.

6、SQL Server 数据查询

一.使用SELECT检索数据 数据查询是SQL语言的中心内容,SELECT 语句的作用是让数据库服务器根据客户要求检索出所需要的信息资料,并按照规定的格式进行整理,返回给客户端. SELECT 语句的基本结构 [WITH<common_tale_expression>] SELECT select_list [INTO new_table_name] [FROM table_source][where search_condition] [GROUP BY group_by_expressio