一行代碼實現FMDB的CURD操作

來源:互聯網
上載者:User

標籤:fmdb   反射   kvc   

上次實現FMDB的CURD基本操作後,用在項目裡,每個實體類都要寫SQL語句來實現建立表和CURD操作,總覺得太麻煩,然後就想著利用反射和kvc來實現一個資料庫操作的基類繼承一下,子類只需要繼承,然後添加自己的屬性就好,這裡做一個總結。

第一個痛點:擷取子類的所有屬性以及類型

OC中有提供擷取所有property的方法,需要用到objc_property_t和class_copyPropertyList。

objc_property_t *properties =class_copyPropertyList([selfclass], &outCount); 數組properties有所有的屬性以及其相應的屬性類型。具體的代碼如下:

/** *  擷取該類的所有屬性 */+ (NSDictionary *)getPropertys{    NSMutableArray *proNames = [NSMutableArray array];    NSMutableArray *proTypes = [NSMutableArray array];    NSArray *theTransients = [[self class] transients];    unsigned int outCount, i;    objc_property_t *properties = class_copyPropertyList([self class], &outCount);    for (i = 0; i < outCount; i++) {        objc_property_t property = properties[i];        //擷取屬性名稱        NSString *propertyName = [NSString stringWithCString:property_getName(property) encoding:NSUTF8StringEncoding];        if ([theTransients containsObject:propertyName]) {            continue;        }        [proNames addObject:propertyName];        //擷取屬性類型等參數        NSString *propertyType = [NSString stringWithCString: property_getAttributes(property) encoding:NSUTF8StringEncoding];        /*         c char         C unsigned char         i int          I unsigned int         l long         L unsigned long         s short        S unsigned short         d double       D unsigned double         f float        F unsigned float         q long long    Q unsigned long long         B BOOL         @ 物件類型 //指標 物件類型 如NSString 是@“NSString”                           64位下long 和long long 都是Tq         SQLite 預設支援五種資料類型TEXT、INTEGER、REAL、BLOB、NULL         */        if ([propertyType hasPrefix:@"[email protected]"]) {            [proTypes addObject:SQLTEXT];        } else if ([propertyType hasPrefix:@"Ti"]||[propertyType hasPrefix:@"TI"]||[propertyType hasPrefix:@"Ts"]||[propertyType hasPrefix:@"TS"]||[propertyType hasPrefix:@"TB"]) {            [proTypes addObject:SQLINTEGER];        } else {            [proTypes addObject:SQLREAL];        }            }    free(properties);        return [NSDictionary dictionaryWithObjectsAndKeys:proNames,@"name",proTypes,@"type",nil];}
propertyTpe 在Xcode document 中,


類型主要是在建立表的時候需要用到,SQLite只支援五種資料類型TEXT、INTEGER、REAL、BLOB、NULL,這裡就需要將擷取到得屬性的類型轉換一下,我主要用了TEXT/INTEGER/REAL三種。

然後就是拼接SQL語句了,這個也比較簡單,建立表的SQL語句拼接在這裡:

+ (NSString *)getColumeAndTypeString{    NSMutableString* pars = [NSMutableString string];    NSDictionary *dict = [self.class getAllProperties];        NSMutableArray *proNames = [dict objectForKey:@"name"];    NSMutableArray *proTypes = [dict objectForKey:@"type"];        for (int i=0; i< proNames.count; i++) {        [pars appendFormat:@"%@ %@",[proNames objectAtIndex:i],[proTypes objectAtIndex:i]];        if(i+1 != proNames.count)        {            [pars appendString:@","];        }    }    return pars;}
第二個痛點:查詢出來的資料賦值給對象的對應屬性

這裡用到了KVC來賦值,主要方法就是setValue:forKey:

依然是先判斷屬性的類型,然後轉換相應的資料類型,我這裡主要是NSString和NSNumber。

if ([columeType isEqualToString:SQLTEXT]) {                    [model setValue:[resultSet stringForColumn:columeName] forKey:columeName];                } else {                    [model setValue:[NSNumber numberWithLongLong:[resultSet longLongIntForColumn:columeName]] forKey:columeName];                }

第三個痛點:子類在執行個體化時,直接建立對應的資料庫表,這裡用dispatch_once實現,只需要建立一次。子類中覆寫createTable方法。

+ (BOOL)createTable{    __block BOOL result = YES;    static dispatch_once_t onceToken;    dispatch_once(&onceToken, ^{        result = [super createTable];    });    return result;}
因為會有多線程操作,所以用單例和FMDatabaseQueue來執行,要避免queue裡調用queue執行操作。

有一些屬性不需要與資料庫表欄位對應,覆寫方法+ (NSArray *)transients;在改方法中返回不需要映射的欄位數組。

基類中的方法如下:

/**  *  擷取該類的所有屬性 */+ (NSDictionary *)getPropertys;/** 擷取所有屬性,包括主鍵 */+ (NSDictionary *)getAllProperties;/** 資料庫中是否存在表 */+ (BOOL)isExistInTable;/** 儲存或更新 * 如果不存在主鍵,儲存, * 有主鍵,則更新 */- (BOOL)saveOrUpdate;/** 儲存單個資料 */- (BOOL)save;/** 批量儲存資料 */+ (BOOL)saveObjects:(NSArray *)array;/** 更新單個資料 */- (BOOL)update;/** 批次更新資料*/+ (BOOL)updateObjects:(NSArray *)array;/** 刪除單個資料 */- (BOOL)deleteObject;/** 大量刪除資料 */+ (BOOL)deleteObjects:(NSArray *)array;/** 通過條件刪除資料 */+ (BOOL)deleteObjectsByCriteria:(NSString *)criteria;/** 查詢全部資料 */+ (NSArray *)findAll;/** 通過主鍵查詢 */+ (instancetype)findByPK:(int)inPk;/** 尋找某條資料 */+ (instancetype)findFirstByCriteria:(NSString *)criteria;/** 通過條件尋找資料  * 這樣可以進行分頁查詢 @" WHERE pk > 5 limit 10" */+ (NSArray *)findByCriteria:(NSString *)criteria;#pragma mark - must be override method/** * 建立表 * 如果已經建立,返回YES */+ (BOOL)createTable;/** 如果子類中有一些property不需要建立資料庫欄位,那麼這個方法必須在子類中重寫  */+ (NSArray *)transients;
具體用法請轉到github下載源碼:https://github.com/Joker-King/JKDBModel


著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

一行代碼實現FMDB的CURD操作

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.