標籤:
http://blog.csdn.net/cooldragon/article/details/18991973
iOS開發中基於ORM的架構很多,如SQLitePersistentObject,實際開發中需求不同或情境不同,方式方法也就不同,有時項目中用不上ORM架構,或者出於公司或項目組習慣或規範、實際項目需求或技術要求等等原因,不會採用完整的ORM架構,但一些重複囉嗦的代碼使用一定的ORM功能還是很能提高效率的。
基於效能或靈活性考慮,或複雜查詢的需求,或項目組要求,項目中資料庫存取一般直接用SQL或用FMDB的多些(某些產品研髮型另說,軟體架構設計是另一個話題,從筆者N年面試N多iOS開發人員來看用FMDB的佔了極大多數,不乏某某有名App),代碼中使用字典、數組或自訂類(或叫實體)作為資料載體,FMDB的FMResultSet有個resultDictionary能夠直接返回字典NSDictionary,再結合下面的輔助類,能夠解決實體物件和字典(NSDictionary)的相互自動轉換問題,不用一個Key一個Key,一個屬性一個屬性的自己去寫代碼了,避免重複手寫煩雜和拼字錯誤的可能,大大的提高了開發效率。
[objc] view plaincopy
- //
- // EntityHelper.h
- // 使用前提條件是:字典的Key和實體物件屬性的單詞是一樣的,大小可以忽略。
- //
- // Created by LongJun on 13-1-28.
- // Copyright (c) 2013年 RL. All rights reserved.
- //
-
- #import <Foundation/Foundation.h>
-
- @interface EntityHelper : NSObject
-
-
- //字典對象轉為實體物件
- + (void) dictionaryToEntity:(NSDictionary *)dict entity:(NSObject*)entity;
-
- //實體物件轉為字典對象
- + (NSDictionary *) entityToDictionary:(id)entity;
-
- @end
[objc] view plaincopy
- //
- // EntityHelper.m
- // ARProjectForPad
- //
- // Created by LongJun on 13-1-28.
- // Copyright (c) 2013年 RL. All rights reserved.
- //
-
- #import "EntityHelper.h"
- #import <objc/runtime.h>
-
- @implementation EntityHelper
-
- #pragma mark - Custom Method
-
- + (void) dictionaryToEntity:(NSDictionary *)dict entity:(NSObject*)entity
- {
- if (dict && entity) {
-
- for (NSString *keyName in [dict allKeys]) {
- //構建出屬性的set方法
- NSString *destMethodName = [NSString stringWithFormat:@"set%@:",[keyName capitalizedString]]; //capitalizedString返回每個單字首大寫的字串(每個單詞的其餘字母轉換為小寫)
- SEL destMethodSelector = NSSelectorFromString(destMethodName);
-
- if ([entity respondsToSelector:destMethodSelector]) {
- [entity performSelector:destMethodSelector withObject:[dict objectForKey:keyName]];
- }
-
- }//end for
-
- }//end if
- }
-
- + (NSDictionary *) entityToDictionary:(id)entity
- {
-
- Class clazz = [entity class];
- u_int count;
-
- objc_property_t* properties = class_copyPropertyList(clazz, &count);
- NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];
- NSMutableArray* valueArray = [NSMutableArray arrayWithCapacity:count];
-
- for (int i = 0; i < count ; i++)
- {
- objc_property_t prop=properties[i];
- const char* propertyName = property_getName(prop);
-
- [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];
-
- // const char* attributeName = property_getAttributes(prop);
- // NSLog(@"%@",[NSString stringWithUTF8String:propertyName]);
- // NSLog(@"%@",[NSString stringWithUTF8String:attributeName]);
-
- id value = [entity performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];
- if(value ==nil)
- [valueArray addObject:[NSNull null]];
- else {
- [valueArray addObject:value];
- }
- // NSLog(@"%@",value);
- }
-
- free(properties);
-
- NSDictionary* returnDic = [NSDictionary dictionaryWithObjects:valueArray forKeys:propertyArray];
- NSLog(@"%@", returnDic);
-
- return returnDic;
- }
-
-
- @end
實際使用(邏輯層)樣本:
[objc] view plaincopy
- //業務需要返回實體物件
- - (UserSCOInfoEntity*)loadStudyRecord:(UserSCOInfoQuery*)query
- {
-
- UserSCOInfoEntity *userSCOInfo = nil;
- @try {
-
- //
- NSDictionary *resultDict = [self loadStudyRecordForDict:query];
- if (!resultDict) return nil;
- //字典值自動填滿到實體物件屬性
- [EntityHelper dictionaryToEntity:resultDict entity:userSCOInfo];
-
- }
- @catch (NSException *exception) {
- NSAssert1(0, @"Exception=%@", exception.reason);
- }
- @finally {
- }
- return userSCOInfo;
- }
-
- //業務需要直接返回字典
- - (NSDictionary*)loadStudyRecordForDict:(UserSCOInfoQuery*)query
- {
- if (!query || !query.userID || !query.courseID || !query.scoID || !query.type || !query.typeID) {
- NSAssert(0, @"UserSCOInfoQuery對象或屬性不可為空");
- return nil;
- }
-
- NSDictionary *resultDict = nil;
- FMDatabase *db = [FMDatabase databaseWithPath:[Common sharedInstance].localMainDb];
- @try {
- if (![db open]) {
- [db release];
- //NSLog(@"db open fail");
- return nil;
- }
-
- FMResultSet *s = [db executeQuery:@"SELECT … "];
- while ([s next]) {
- resultDict = [s resultDictionary];
- break;
- }
- [s close];
-
- if (!resultDict) {
- // NSString *errMsg = [db lastErrorMessage];
- //NSLog(@"[db lastErrorMessage]=%@",errMsg);
- }
- }
- @catch (NSException *exception) {
- NSAssert1(0, @"Exception=%@", exception.reason);
- }
- @finally {
- [db close];
- }
- return resultDict;
- }
當然,以上代碼有一定應用情境,有一定的局限性,比如:
字典的Key和實體物件屬性的單詞必須是一樣的(大小可以忽略),這裡沒有使用外部對應檔主要也是為了簡化代碼和項目的需要決定的。
Objective-C中ORM的運用:實體物件和字典的相互自動轉換