標籤:des style blog http io color ar os 使用
提到資料庫就不得不提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