Core Data是iOS5之后才出现的一个框架,它提供了对象-关系映射(ORM)的功能,即能够将OC对象转化成数据,保存在SQLite数据库文件中,也能够将保存在数据库中的数据还原成OC对象。在此数据操作期间,我们不需要编写任何SQL语句,这个有点类似于著名的Hibernate持久化框架,不过功能肯定是没有Hibernate强大的。简单地用下图描述下它的作用:
左边是关系模型,即数据库,数据库里面有张person表,person表里面有id、name、age三个字段,而且有2条记录;
右边是对象模型,可以看到,有2个OC对象;
利用Core Data框架,我们就可以轻松地将数据库里面的2条记录转换成2个OC对象,也可以轻松地将2个OC对象保存到数据库中,变成2条表记录,而且不用写一条SQL语句。
右图中的表示Card中有个Person类型的person属性,目的就是建立Card跟Person之间的一对一关联关系(建议补上这一项),在Person中加上Inverse属性后,你会发现Card中Inverse属性也自动补上了
2. NSManagedObject 的工作模式有点类似于 NSDictionary 对象,通过键 - 值对来存取所有的实体属性
1> setValue:forKey:存储属性值(属性名为key)
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 不一样就可以了。
//查询请求
NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"User"];
//排序
NSSortDescriptor *des=[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES];
[request setSortDescriptors:@[des]];
-------------使用谓词限定条件------------------
// 设置条件过滤(搜索name中包含字符串"Itcast-1"的记录,注意:设置条件过滤时,数据库SQL语句中的%要用*来代替,所以%Itcast-1%应该写成*Itcast-1*)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"];
request.predicate = predicate;
--------------------------------------------
//执行查询
NSArray *array=[_context executeFetchRequest:request error:nil];
#import "AZViewController.h" #import "User.h" #import "INFO.h" @interface AZViewController () { //CoreData 上下文对象指针 NSManagedObjectContext *_context; } @end @implementation AZViewController - (void)viewDidLoad { [super viewDidLoad]; [self initCoreData]; } #pragma mark -- 初始化CoreDate -(void)initCoreData { //01 将托管对象--(即是数据模型)托管给协调者 //拿到托管对象--user NSManagedObjectModel *userModel=[NSManagedObjectModel mergedModelFromBundles:nil];//如果参数为nil,会将所有的托管对象都获取到。在这里我们只有一个User。所以就只拿出User这一个托管对象。 //创建协调者 NSPersistentStoreCoordinator *coordinator=[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:userModel]; //数据库路径 NSString *path=[NSString stringWithFormat:@"%@/Documents/data2.db",NSHomeDirectory()]; //关联数据库 [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:[NSURL fileURLWithPath:path] options:nil error:nil]; //02 创建上下文,关联协调者 _context=[[NSManagedObjectContext alloc] init]; _context.persistentStoreCoordinator=coordinator; } - (IBAction)addData:(id)sender { //创建一个User对象 #if 1 User *user=[NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:_context]; user.name=_name.text; user.score=[NSNumber numberWithInt:[_score.text intValue]]; user.info=[NSEntityDescription insertNewObjectForEntityForName:@"INFO" inManagedObjectContext:_context]; user.info.age=[NSNumber numberWithInt:21]; user.info.sex=@"男"; if ([_context save:nil]) { NSLog(@"保存成功"); }else { NSLog(@"保存失败"); } #endif #if 0 //注意CoreData中不能这样创建对象,必须按上面的方式创建对象。 User *user=[[User alloc] init]; user.name=@"zzz"; user.score=[NSNumber numberWithInt:100]; [_context insertObject:user]; [_context save:nil]; #endif } - (IBAction)delData:(id)sender { //查询请求 NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"User"]; //排序 NSSortDescriptor *des=[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES]; [request setSortDescriptors:@[des]]; //执行查询 NSArray *array=[_context executeFetchRequest:request error:nil]; for (User *user in array) { if ([user.name isEqualToString:_name.text]) { [_context deleteObject:user]; if ([_context save:nil])//原子性操作 { NSLog(@"修改成功"); } } } } - (IBAction)changeData:(id)sender { //查询请求 NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"User"]; //排序 NSSortDescriptor *des=[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES]; [request setSortDescriptors:@[des]]; // 设置条件过滤(搜索name中包含字符串"Itcast-1"的记录,注意:设置条件过滤时,数据库SQL语句中的%要用*来代替,所以%Itcast-1%应该写成*Itcast-1*) NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name like %@", @"*Itcast-1*"]; request.predicate = predicate; //执行查询 NSArray *array=[_context executeFetchRequest:request error:nil]; for (User *user in array) { if ([user.name isEqualToString:_name.text]) { user.score=[NSNumber numberWithInt:[_score.text intValue]]; if ([_context save:nil])//原子性操作 { NSLog(@"修改成功"); } } } } - (IBAction)selectData:(id)sender { //查询请求 NSFetchRequest *request=[[NSFetchRequest alloc] initWithEntityName:@"User"]; //排序 NSSortDescriptor *des=[NSSortDescriptor sortDescriptorWithKey:@"score" ascending:YES]; [request setSortDescriptors:@[des]]; //执行查询 NSArray *array=[_context executeFetchRequest:request error:nil]; showDataView.text=@""; for (User *user in array) { showDataView.text=[NSString stringWithFormat:@"%@name:%@ score:%d\n age:%d sex:%@",showDataView.text,user.name,[user.score intValue],[user.info.age intValue],user.info.sex]; } } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [_name resignFirstResponder]; [_score resignFirstResponder]; } @end