提到数据库就不得不提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)

posted on 2014-11-17 11:06  幸福小弥  阅读(596)  评论(0编辑  收藏  举报