• Objective-C中ORM的运用:实体对象和字典的相互自动转换


    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在CODE上查看代码片派生到我的代码片
     
    1. //  
    2. //  EntityHelper.h  
    3. //  使用前提条件是:字典的Key和实体对象属性的单词是一样的,大小可以忽略。  
    4. //  
    5. //  Created by LongJun on 13-1-28.  
    6. //  Copyright (c) 2013年 RL. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. @interface EntityHelper : NSObject  
    12.   
    13.   
    14. //字典对象转为实体对象  
    15. + (void) dictionaryToEntity:(NSDictionary *)dict entity:(NSObject*)entity;  
    16.   
    17. //实体对象转为字典对象  
    18. + (NSDictionary *) entityToDictionary:(id)entity;  
    19.   
    20. @end  
    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. //  
    2. //  EntityHelper.m  
    3. //  ARProjectForPad  
    4. //  
    5. //  Created by LongJun on 13-1-28.  
    6. //  Copyright (c) 2013年 RL. All rights reserved.  
    7. //  
    8.   
    9. #import "EntityHelper.h"  
    10. #import <objc/runtime.h>  
    11.   
    12. @implementation EntityHelper  
    13.   
    14. #pragma mark - Custom Method  
    15.   
    16. + (void) dictionaryToEntity:(NSDictionary *)dict entity:(NSObject*)entity  
    17. {  
    18.     if (dict && entity) {  
    19.           
    20.         for (NSString *keyName in [dict allKeys]) {  
    21.             //构建出属性的set方法  
    22.             NSString *destMethodName = [NSString stringWithFormat:@"set%@:",[keyName capitalizedString]]; //capitalizedString返回每个单词首字母大写的字符串(每个单词的其余字母转换为小写)  
    23.             SEL destMethodSelector = NSSelectorFromString(destMethodName);  
    24.               
    25.             if ([entity respondsToSelector:destMethodSelector]) {  
    26.                 [entity performSelector:destMethodSelector withObject:[dict objectForKey:keyName]];  
    27.             }  
    28.               
    29.         }//end for  
    30.           
    31.     }//end if  
    32. }  
    33.   
    34. + (NSDictionary *) entityToDictionary:(id)entity  
    35. {  
    36.       
    37.     Class clazz = [entity class];  
    38.     u_int count;  
    39.       
    40.     objc_property_t* properties = class_copyPropertyList(clazz, &count);  
    41.     NSMutableArray* propertyArray = [NSMutableArray arrayWithCapacity:count];  
    42.     NSMutableArray* valueArray = [NSMutableArray arrayWithCapacity:count];  
    43.       
    44.     for (int i = 0; i < count ; i++)  
    45.     {  
    46.         objc_property_t prop=properties[i];  
    47.         const char* propertyName = property_getName(prop);  
    48.           
    49.         [propertyArray addObject:[NSString stringWithCString:propertyName encoding:NSUTF8StringEncoding]];  
    50.           
    51.         //        const char* attributeName = property_getAttributes(prop);  
    52.         //        NSLog(@"%@",[NSString stringWithUTF8String:propertyName]);  
    53.         //        NSLog(@"%@",[NSString stringWithUTF8String:attributeName]);  
    54.           
    55.         id value =  [entity performSelector:NSSelectorFromString([NSString stringWithUTF8String:propertyName])];  
    56.         if(value ==nil)  
    57.             [valueArray addObject:[NSNull null]];  
    58.         else {  
    59.             [valueArray addObject:value];  
    60.         }  
    61.         //        NSLog(@"%@",value);  
    62.     }  
    63.       
    64.     free(properties);  
    65.       
    66.     NSDictionary* returnDic = [NSDictionary dictionaryWithObjects:valueArray forKeys:propertyArray];  
    67.     NSLog(@"%@", returnDic);  
    68.       
    69.     return returnDic;  
    70. }  
    71.   
    72.   
    73. @end  


    实际使用(逻辑层)示例:

    [objc] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. //业务需要返回实体对象  
    2. - (UserSCOInfoEntity*)loadStudyRecord:(UserSCOInfoQuery*)query  
    3. {  
    4.       
    5.     UserSCOInfoEntity *userSCOInfo = nil;  
    6.     @try {  
    7.           
    8.         //  
    9.         NSDictionary *resultDict = [self loadStudyRecordForDict:query];  
    10.         if (!resultDict) return nil;  
    11.         //字典值自动填充到实体对象属性  
    12.         [EntityHelper dictionaryToEntity:resultDict entity:userSCOInfo];  
    13.           
    14.     }  
    15.     @catch (NSException *exception) {  
    16.         NSAssert1(0, @"Exception=%@", exception.reason);  
    17.     }  
    18.     @finally {  
    19.     }  
    20.     return userSCOInfo;  
    21. }  
    22.   
    23. //业务需要直接返回字典  
    24. - (NSDictionary*)loadStudyRecordForDict:(UserSCOInfoQuery*)query  
    25. {  
    26.     if (!query || !query.userID || !query.courseID || !query.scoID || !query.type || !query.typeID) {  
    27.         NSAssert(0, @"UserSCOInfoQuery对象或属性不能为空");  
    28.         return nil;  
    29.     }  
    30.       
    31.     NSDictionary *resultDict = nil;  
    32.     FMDatabase *db = [FMDatabase databaseWithPath:[Common sharedInstance].localMainDb];  
    33.     @try {  
    34.         if (![db open]) {  
    35.             [db release];  
    36.             //NSLog(@"db open fail");  
    37.             return nil;  
    38.         }  
    39.           
    40.         FMResultSet *s = [db executeQuery:@"SELECT … "];  
    41.         while ([s next]) {  
    42.             resultDict = [s resultDictionary];  
    43.             break;  
    44.         }  
    45.         [s close];  
    46.           
    47.         if (!resultDict) {  
    48. //            NSString *errMsg = [db lastErrorMessage];  
    49.             //NSLog(@"[db lastErrorMessage]=%@",errMsg);  
    50.         }  
    51.     }  
    52.     @catch (NSException *exception) {  
    53.         NSAssert1(0, @"Exception=%@", exception.reason);  
    54.     }  
    55.     @finally {  
    56.         [db close];  
    57.     }  
    58.     return resultDict;  
    59. }  



    当然,以上代码有一定应用场景,有一定的局限性,比如:
    字典的Key和实体对象属性的单词必须是一样的(大小可以忽略),这里没有使用外部映射文件主要也是为了简化代码和项目的需要决定的。 

  • 相关阅读:
    基于短周期价量特征的多因子选股体系
    OnePy--构建属于自己的量化回测框架
    Should You Build Your Own Backtester?
    针对Quant的Python快速入门指南
    史上最全量化资源整理
    数字货币量化分析报告[2018-01-31]
    TuShare获取K线数据
    理工科背景如何转行量化交易?
    数字货币量化分析报告[2018-01-30]
    Ta-lib K线模式识别
  • 原文地址:https://www.cnblogs.com/xuejinhui/p/4469626.html
Copyright © 2020-2023  润新知