EasyDataKit 簡單易用的 SQLite 輪子

熱血pk007 9年前發布 | 11K 次閱讀 SQLite iOS開發 移動開發

EasyDataKit 是一個基于 FMDB 封裝的庫,它可以免去開發者編寫復雜 SQL 的困擾,更加專注業務上的事情,從而提高開發效率。

特征

  • 類 ORM 接口
  • 自動創建庫和表,支持表新增字段的修改
  • 支持 where 查詢語句
  • 自動事務提升插入效率

使用

EasyDataKit 適用于將網絡請求的數據持久化到數據庫中,特別是處理網絡請求數據時不習慣把數據轉換成 model。筆者的淺見是:轉換對性能是有消耗的,獲得的可讀性好處也可以通過字符串常量解決。

假設你通過網絡請求獲取到了數據:

{
    "data": {
        "id": "56d177a27cb3331100465f72",
        "messagePrefix": "飯否每日精選",
        "content": "飯否每日精選",
        "topicId": 1345,
        "briefIntro": "飯否是國內著名的小眾輕博客社區,氛圍獨特,清新自由。關注飯否每日精選,看看塵囂之外,大家談論什么。",
        "keywords": "飯否 精選 短博客 社區",
        "timeForRank": "2016-02-27T11:06:30.731Z",
        "lastMessagePostTime": "2016-11-06T02:42:52.111Z",
        "topicPublishDate": "2016-02-26T16:00:00.000Z",
        "createdAt": "2016-02-27T10:17:06.295Z",
        "updatedAt": "2016-11-01T04:30:08.973Z",
        "subscribersCount": 1207100,
        "subscribedStatusRawValue": 1,
        "subscribedAt": "2016-10-18T09:57:24.424Z",
        "rectanglePicture": {
            "thumbnailUrl": "https://cdn.ruguoapp.com/o_1ach3c6o011j91ljjtmdhlhnffo.jpg?imageView2/1/w/120/h/180",
            "middlePicUrl": "https://cdn.ruguoapp.com/o_1ach3c6o011j91ljjtmdhlhnffo.jpg?imageView2/1/w/200/h/300",
            "picUrl": "https://cdn.ruguoapp.com/o_1ach3c6o011j91ljjtmdhlhnffo.jpg?imageView2/0/h/1000",
            "format": "png"
        },
        "squarePicture": {
            "thumbnailUrl": "https://cdn.ruguoapp.com/o_1ach6nm599m94re1gvj14r71jaso.jpg?imageView2/0/w/120/h/120",
            "middlePicUrl": "https://cdn.ruguoapp.com/o_1ach6nm599m94re1gvj14r71jaso.jpg?imageView2/0/w/300/h/300",
            "picUrl": "https://cdn.ruguoapp.com/o_1ach6nm599m94re1gvj14r71jaso.jpg?imageView2/0/h/1000",
            "format": "png"
        },
        "pictureUrl": "https://cdn.ruguoapp.com/o_1ach3c6o011j91ljjtmdhlhnffo.jpg?imageView2/1/w/200/h/300",
        "thumbnailUrl": "https://cdn.ruguoapp.com/o_1ach6nm599m94re1gvj14r71jaso.jpg?imageView2/0/w/300/h/300"
    }
}

你可將這段 JSON String 轉換成 Dictionary 或 Array:

NSDictionary *dictionary = [NSJSONSerializationJSONObjectWithData:dataoptions:NSJSONReadingAllowFragmentserror:nil]; 
NSDictionary *subscribe = dictionary[@"data"];

接著便可使用 EasyDataKit 的 API 進行存儲:

EDKEntity *subscribeEntity = [[EDKEntity alloc]initWithTableName:@"subcribes"dbName:nil];
[subscribeEntitysaveData:subscribeprimaryColumn:@"id"relationShip:nilindexes:nil];

可以手動為數據添加列,實現滿足業務的需求:

NSMutableDictionary *subcribeInfo = [[NSMutableDictionary alloc]initWithDictionary:subscribe];
[subcribeInfosetObject:<a ];
EDKEntity *subscribeEntity = [[EDKEntity alloc]initWithTableName:@"subcribes"dbName:nil]; [subscribeEntitysaveData:subcribeInfoprimaryColumn:@"id"relationShip:nilindexes:nil];

如果你想讓某紀錄關聯其它對象,可以將對象存儲后返回的 id 作為 value,key 是該紀錄原本對應該對象的字段,這相當于用 id 這個值去替換原本字段對應的對象,從而達到拆分的目的:

id rowId = [rectanglePictureEntitysaveData:subscribe[@"rectanglePicture"]primaryColumn:nilrelationShip:nil];
EDKEntity *subscribeEntity = [[EDKEntity alloc]initWithTableName:@"subcribes"dbName:nil];
[subscribeEntitysaveData:subscribeprimaryColumn:@"id"relationShip:@{@"rectanglePicture": rowId}indexes:nil];

EasyDataKit 還可以存儲索引

NSDictionary *subcribeInfo = [[NSDictionary alloc]initWithDictionary:subscribe];
EDKEntity *subscribeEntity = [[EDKEntity alloc]initWithTableName:@"subcribes"dbName:@"TestIndex"];
[subscribeEntitysaveData:subcribeInfoprimaryColumn:nilrelationShip:nilindexes:@[@[@"topicId"], @[@"content", @"messagePrefix"]]];

對存儲來說,EasyDataKit 還提供了自動 ALTER TABLE 添加列的功能,方便開發者應對升級,原理是當檢測到待存儲的字典 keys 數組元素個數比之前已經在表中的列多時,則會自動為表添加新的列,即并不支持修改列和刪除列的操作,而 EasyDataKit 對創建的索引是支持修改刪除的。

查詢:

// select by id
EDKEntity *entity = [[EDKEntity alloc]initWithTableName:@"messages"dbName:nil];
id object = [entityqueryByPrimaryKey:@"581d2fdb36a4471100e311d6"withColumns:@[@"topicId", @"commentCount", @"topic"]];
NSLog(@"%@", object);
NSArray *objects = [entityqueryWithColumns:nilwhere:@"WHERE commentCount < ? and read = ?"arguments:@[@20, @1]]; 
NSLog(@"%@", objects);

查詢嵌套對象并將其轉換為 Dictionary 或 Array:

EDKEntity *subcribeEntity = [[EDKEntity alloc]initWithTableName:@"subcribes"dbName:nil];
 
// select by id id
subcribe = [subcribeEntityqueryByPrimaryKey:@"56d177a27cb3331100465f72"withColumns:@[@"squarePicture"]];
 
// subcribe is a json string
NSData *data = [subcribe[@"squarePicture"]dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *jsonDict = [NSJSONSerializationJSONObjectWithData:dataoptions:0error:&error]; 
NSLog(@"JSONDict: %@", jsonDict);

更新:

EDKEntity *entity = [[EDKEntity alloc]initWithTableName:@"messages"dbName:nil]; 
[entityupdateByPrimaryKey:@"5805905a319a9c1200833660"set:@{@"read": @"0", @"commentCount": @99}];
[entityupdateWithSet:@{@"messageId": @"2333333"}where:@"WHERE commentCount > ?"arguments:@[@50]];

刪除:

EDKEntity *entity = [[EDKEntity alloc]initWithTableName:@"messages"dbName:nil];
 
// delete by id
 
[entitydeleteByPrimaryKey:@"5805905a319a9c1200833660"];
 
// delete by where
 
[entitydeleteWithWhere:@"WHERE popularity = ?"arguments:@[@"93"]];
 
// delete all
 
[entitydeleteAll];
EDKEntity *entity = [[EDKEntity alloc]initWithTableName:@"messages"dbName:nil];
// delete by id
[entitydeleteByPrimaryKey:@"5805905a319a9c1200833660"];
 
// delete by where
[entitydeleteWithWhere:@"WHERE popularity = ?"arguments:@[@"93"]];
 
// delete all
[entitydeleteAll];

由上面可以看出,只要創建出 EDKEntity 對象,就可以輕松加愉快地進行存儲,查找,修改,刪除操作。開發者無需創建數據庫、表,EasyDataKit 也支持 db 的劃分,但不提供內存緩存,原因是筆者認為沒有熱塊的數據庫緩存意義不是太大。當有寫操作發生的時候,EasyDataKit 會通過輪詢的事務機制打包寫操作,從而提高頻繁寫操作的效率。(更詳細的使用請移步 EasyDataKit 中的 Example)

源碼簡析

EasyDataKit 有個 swizzle 了 NSMutableDictionary 的 setObject:forKey: 和 NSMutableArray 的 addObject:,使得應對空值不會 crash。

EasyDataKit 還有個遞歸方法:dealWithObject:,主要有兩個用途:一是用來檢測除了 NSDictionary、NSArray、NSString、NSNumber、NSNull 這些類型以外的合法性,譬如 UIView 類型直接調用 description 轉換成字符串;二是為了能讓嵌套的 Dictionary 或 Array 以 JSON String 的形式存入數據庫,在取出后仍可以將其轉換回 Dictionary 或 Array。

DISPATCH_SOURCE_TYPE_TIMER 創建的定時器。

 

 

來自:http://ios.jobbole.com/90509/

 

 本文由用戶 熱血pk007 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!