首页 > 代码库 > IOS存储(2)使用coredata

IOS存储(2)使用coredata

提到数据库就不得不提ORM,ORM是指将存储的数据表与对象关联起来,通过操作对象与对象间的关系来操作数据库中的数据,java中最常用的ORM框架有Hibernate,Mybatis,这些都是第三方开源框架,而在IOS中苹果官方直接提供了CoreData

CoreData中重要概念

1:PersistentStore

这是数据存储的地方,IOS提供了多种persistentstore供开发者选择,除了sqlite3数据库,还有二进制文件,xml文件以及内存,开发者主要使用的是第一种而后面三种使用的较少

 

2:NSManagedObjectModel

数据模型,相当于数据库中所有的表格,IOS提供了xcdatamodeld文件建立数据模型,一个数据模型可以包含多个实体,实体有各自的属性,实体间也可以存在关系,xcdatamodeld编译后是编译为.momd文件

常见的初始化方法如下

- (NSManagedObjectModel *)managedObjectModel{    if (_managedObjectModel != nil) {        return _managedObjectModel;    }//    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"coredatademo" withExtension:@"momd"];//    _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];        //nil代表mainbundle    _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];    return _managedObjectModel;}

mergedModelFromBundles:nil 连接项目中所有的 .xcdatamodeld 文件为一个datamodel,这是一个非常好的方法,把多个entity放在各自的xcodemodel文件中分开管理,然后用这个函数连接起来生成一个datamodel,这样就可以对应一个persistentStore

 

3:NSPersistentStoreCoordinator

通过PersistentStoreCoordinator设置数据存储的名字,位置,存储方式,和存储时机,将数据模型与PersistentStore联系起来

初始化方法如下

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator{    if (_persistentStoreCoordinator != nil) {        return _persistentStoreCoordinator;    }        NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"coredatademo.sqlite"];        NSError *error = nil;    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);        abort();    }            return _persistentStoreCoordinator;}

 

我们通过initWithManagedObjectModel初始化一个persistentStoreCoordinator,初始化方法中指定了数据模型(managedObjectModel),然后通过addPersistentStoreWithType方法指定了数据模型的存储方法是sqlite数据库,并且通过URL指定了数据库文件路径。

除了NSSQLiteStoreType外还可以设置以下几种PersistentStore

COREDATA_EXTERN NSString * const NSSQLiteStoreType NS_AVAILABLE(10_4, 3_0);

COREDATA_EXTERN NSString * const NSXMLStoreType NS_AVAILABLE(10_4, NA);

COREDATA_EXTERN NSString * const NSBinaryStoreType NS_AVAILABLE(10_4, 3_0);

COREDATA_EXTERN NSString * const NSInMemoryStoreType NS_AVAILABLE(10_4, 3_0);

 

4:NSManagedObject:实体对象,定义了数据的结构,但他并不是数据,真正的数据实例是NSManagedObject类或他的子类,每个NSManagedObject对象对应着数据库表中一条记录。

 

5:NSManagedObjectContext

数据的操作全部都在managedObjectsContext中完成

初始化方法如下

- (NSManagedObjectContext *)managedObjectContext{    if (_managedObjectContext != nil) {        return _managedObjectContext;    }        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];    if (coordinator != nil) {        _managedObjectContext = [[NSManagedObjectContext alloc] init];        [_managedObjectContext setPersistentStoreCoordinator:coordinator];    }    return _managedObjectContext;}

 

6:NSEntityDescription:表格结构

 

7:NSFetchRequest:查询语句

 

CoreData使用流程 

1:建立数据模型

File->New->File->Core Data->DataModel新建一个数据模型文件 

然后AddEntity添加实体

实体重命名为MyEntity,并为实体添加name和birthday两个属性

 

2:生成NSManagedObject

Editor->Create NSManagedObject Subclass,然后选择DataModel和DataModel中的Entity,自动生成我们的managedObject

@interface MyEntity : NSManagedObject@property (nonatomic, retain) NSString * name;@property (nonatomic, retain) NSDate * birthday;@end@implementation MyEntity@dynamic name;@dynamic birthday;@end

 

3:设置NSManagedObjectContext

在需要使用CoreData存储的ViewController中初始化我们的NSManagedObjectContext

- (void)viewDidLoad{    [super viewDidLoad];    NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];        NSString *pathdir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];    NSString *path = [pathdir stringByAppendingPathComponent:@"coredata.sqlite"];    NSLog(@"%@",pathdir);    NSURL *url = [NSURL fileURLWithPath:path];        NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];    [coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:nil];            _managedObjectContext = [[NSManagedObjectContext alloc] init];    [_managedObjectContext setPersistentStoreCoordinator:coordinator];}

 

上面的代码初始化NSManagedObjectContext后需要设定persistentStoreCoordinato,而coordinator初始化时需要设置DataModel以及存储文件,存储方式

 

 

4:存储实体对象

- (IBAction)saveEntity:(id)sender {    MyEntity *entity = [NSEntityDescription insertNewObjectForEntityForName:@"MyEntity" inManagedObjectContext:_managedObjectContext];    entity.name = @"zaglitao";    entity.birthday = [NSDate date];        NSError *error;    if (![_managedObjectContext save:&error]) {        NSLog(@"保存实体出错");    }}

我们进入Edit Scheme->run->Arguments 添加-com.apple.CoreData.SQLDebug 1,这样控制台就能打印出SQL语句

2014-11-17 10:50:44.862 DataStoreDemo[1749:607] CoreData: sql: BEGIN EXCLUSIVE

2014-11-17 10:50:44.863 DataStoreDemo[1749:607] CoreData: sql: INSERT INTO ZMYENTITY(Z_PK, Z_ENT, Z_OPT, ZBIRTHDAY, ZNAME) VALUES(?, ?, ?, ?, ?)

2014-11-17 10:50:44.863 DataStoreDemo[1749:607] CoreData: sql: COMMIT

可以发现CoreData建立的数据库表和属性在我们设置的基础上加了字母Z

 

5:查询实体对象

- (IBAction)getEntity:(id)sender {    NSFetchRequest *request = [[NSFetchRequest alloc] init];    NSEntityDescription *description = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:_managedObjectContext];        [request setEntity:description];    request.predicate = [NSPredicate predicateWithFormat:@"name like %@",@"zanglitao"];        NSError *error;    NSArray *array = [_managedObjectContext executeFetchRequest:request error:&error];        NSLog(@"%@",array);}

 SELECT 0, t0.Z_PK, t0.Z_OPT, t0.ZBIRTHDAY, t0.ZNAME FROM ZMYENTITY t0 WHERE  NSCoreDataLike( t0.ZNAME, ?, 0)

 

6:更改实体对象

- (IBAction)updateEntity:(id)sender {    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];    request.predicate = [NSPredicate predicateWithFormat:@"name like ‘zaglitao‘"];    NSArray *array = [_managedObjectContext executeFetchRequest:request error:nil];            MyEntity *entity = [array firstObject];    entity.name = @"zanglitao";        NSError *error;    if (![_managedObjectContext save:&error]) {        NSLog(@"更新实体出错");    }}

2014-11-17 10:52:36.496 DataStoreDemo[1749:607] CoreData: sql: BEGIN EXCLUSIVE

2014-11-17 10:52:36.497 DataStoreDemo[1749:607] CoreData: sql: UPDATE ZMYENTITY SET ZNAME = ?, Z_OPT = ?  WHERE Z_PK = ? AND Z_OPT = ?

2014-11-17 10:52:36.497 DataStoreDemo[1749:607] CoreData: sql: COMMIT

 

7:删除实体对象

- (IBAction)deleteEntity:(id)sender {    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];    request.predicate = [NSPredicate predicateWithFormat:@"name like ‘zanglitao‘"];    NSArray *array = [_managedObjectContext executeFetchRequest:request error:nil];            MyEntity *entity = [array firstObject];    [_managedObjectContext deleteObject:entity];        NSError *error;    if (![_managedObjectContext save:&error]) {        NSLog(@"删除实体出错");    }}

2014-11-17 10:53:00.287 DataStoreDemo[1749:607] CoreData: sql: BEGIN EXCLUSIVE

2014-11-17 10:53:00.287 DataStoreDemo[1749:607] CoreData: sql: DELETE FROM ZMYENTITY WHERE Z_PK = ? AND Z_OPT = ?

2014-11-17 10:53:00.310 DataStoreDemo[1749:607] CoreData: sql: COMMIT

 

设置实体关系(一个User对应多个Phone)

IOS存储(2)使用coredata