iOS - 最易用的數(shù)據(jù)庫工具類 `XWDatabase` 開源

iOS - 最易用的數(shù)據(jù)庫工具類 XWDatabase 開源

XWDatabase GitHub 地址:https://github.com/qxuewei/XWDatabase

XWDatabase 的亮點

  • 將數(shù)據(jù)庫操作簡化到難以想象的程度赶促,你甚至不需要知道數(shù)據(jù)庫的存在贰谣,當然更不需要寫 SQL 語句,你只需要直接操作模型即可對模型進行增刪改查的操作宁玫,她會根據(jù)模型動態(tài)在數(shù)據(jù)庫中創(chuàng)建以當前模型類名為名稱的數(shù)據(jù)庫表颠黎,當然你也可以自定義表名笤成;
  • 她會根據(jù)模型的成員變量和成員變量的類型動態(tài)進行字段的設計需频,有多少成員變量,表中自然就會有多少字段與其對應埠况,當然耸携,你也可以忽略其中的某些你不想存儲的成員變量,也可以自定義字段的名稱辕翰;
  • 如果哪天模型的字段變化了夺衍,她會自動進行表中原有字段的更新,而且無論原表中有多少數(shù)據(jù)喜命,都會一條不落的遷移到新表中沟沙;
  • 她的API簡單到只有一行代碼,你無需關注數(shù)據(jù)庫的開啟和關閉壁榕,一行代碼實現(xiàn)增刪改查和數(shù)據(jù)遷移;
  • 你甚至可以在任何線程中調用她的API牌里,她一定是線程安全的,不會出現(xiàn)多線程訪問同一個數(shù)據(jù)庫和死鎖的問題牡辽;
  • 數(shù)據(jù)操作是耗時操作,所以你無需手動開啟異步線程操作數(shù)據(jù)庫操作态辛,她會統(tǒng)一在一個焙枷叮活的異步線程中執(zhí)行;
  • 她支持存儲常見的數(shù)據(jù)類型(int、long票髓、signed、float洽沟、double以故、NSInteger、CGFloat裆操、BOOL炉媒、NSString昆烁、NSMutableString、NSNumber静尼、NSArray、NSMutableArray鸭巴、NSDictionary、NSMutableDictionary鹃祖、NSData普舆、NSMutableData、UIImage奔害、NSDate华临、NSURL芯杀、NSRange揭厚、CGRect扶供、CGSize、CGPoint椿浓、自定義對象等的存儲);
  • 她還對二進制文件的存儲做了優(yōu)化扳碍,比如同一張圖片表中所有數(shù)據(jù)都持有這張圖片對象,她在數(shù)據(jù)庫中只會有一份拷貝碱蒙,竭盡她所能優(yōu)化存儲空間。

筆鋒一轉哀墓,V1.0 版本會存在很多不足喷兼,希望各位前輩和大牛多多指正,多提 issues

下面簡述一下此庫的一些設計思路和使用方法

使用

一褒搔、增

1.保存一個模型
- (void)saveOnePerson
{
    XWPerson *person = [XWPerson testPerson:2];
    [XWDatabase saveModel:person completion:^(BOOL isSuccess) {

    }];
}

實例化一個對象星瘾, 調用 saveModel 方法。

2.保存多個模型
- (void)saveModels
{
    NSMutableArray *persons = [[NSMutableArray alloc] init];
    for (int i = 0; i < 1000; i++) {
        [persons addObject:[XWPerson testPerson:i]];
    }
    [XWDatabase saveModels:persons completion:^(BOOL isSuccess) {
        
    }];
}

實例化一堆對象琳状, 調用 saveModels 方法。

二困食、刪

1.刪除一個模型
- (void)deleteModel
{
    XWPerson *person = [XWPerson new];
    person.cardID = @"1"; /// 指定想刪除的主鍵(或聯(lián)合主鍵)
    [XWDatabase deleteModel:person completion:^(BOOL isSuccess) {
        
    }];
}

實例化一個對象翎承,為主鍵賦值(得知道刪的是哪個,讓她猜瘩例,臣妾做不到)甸各, 調用 deleteModel 方法。

2.刪除此模型存儲的所有數(shù)據(jù)
- (void)clearModel
{
    [XWDatabase clearModel:XWPerson.class completion:^(BOOL isSuccess) {

    }];
}

調用 clearModel 方法聘惦,傳入想刪除的模型類

3.選擇性刪除此模型存儲的數(shù)據(jù)
/// 刪除 age > 50 的數(shù)據(jù)
- (void)clearModel
{
    [XWDatabase clearModel:XWPerson.class condition:@"age > '50'" completion:^(BOOL isSuccess) {
        
    }];
}

調用 clearModel 方法儒恋,傳入想刪除的模型類和條件

三、改

1.更新某模型某個成員變量 (選擇性更新)
/// 改名
- (void)updateModel
{
    XWPerson *person = [XWPerson new];
    person.cardID = @"2";
    person.name = @"新名字";
    
    /// 自定義成員變量更新
    [XWDatabase updateModel:person updatePropertys:@[@"name"] completion:^(BOOL isSuccess) {
        
   }];
    
}

實例化一個對象涂邀,為主鍵和有變化的成員變量賦值箱锐, 調用 updateModel 方法劳较,傳入想更新的成員變量名稱浩聋。

2.更新某模型所有數(shù)據(jù) (全量更新)
/// 根據(jù)傳入的模型整體更新
- (void)updateModel
{
    XWPerson *person = [XWPerson new];
    person.cardID = @"2";
    person.name = @"新名字";
    person.girls = @[@"小妹",@"须担花",@"小baby"];
    
    /// 整個模型更新
    [XWDatabase saveModel:person completion:^(BOOL isSuccess) {
        
    }];
    
}

實例化一個對象抖仅, 調用 updateModel 方法,傳入想更新的模型撤卢。

四、查

1.根據(jù)主鍵查詢模型
- (void)getOnePerson
{
    XWPerson *person = [XWPerson new];
    person.cardID = @"81";
    [XWDatabase getModel:person completion:^(XWPerson * obj) {
        
    }];
}

實例化一個對象智听,為主鍵賦值渡紫, 調用 getModel 方法。

2.查詢數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù)
- (void)getModels
{
    [XWDatabase getModels:XWPerson.class completion:^(NSArray * _Nullable objs) {
        
        
    }];
}

調用 getModels 方法莉测,傳入模型類

3.查詢數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 按某成員變量排序
/// 獲取數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 按 age 字段降序排列
- (void)getModelsSortAge
{
    [XWDatabase getModels:XWPerson.class sortColumn:@"age" isOrderDesc:YES completion:^(NSArray * _Nullable objs) {
        
    }];
}

調用 getModels 方法,傳入模型類和要排序的字段

4.查詢數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 自定義查詢條件
/// 獲取數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 自定義查找條件 (例如模糊查詢 name 含 學偉 的數(shù)據(jù))
- (void)getModelsCondition
{
    [XWDatabase getModels:XWPerson.class condition:@"name like '%學偉'" completion:^(NSArray * _Nullable objs) {
        
    }];
}

調用 getModels 方法捣卤,傳入模型類和查詢的條件

5.查詢數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 自定義查詢條件并且可按照某字段排序
/// 獲取數(shù)據(jù)庫中所有該模型存儲的數(shù)據(jù) - 自定義查找條件可排序 (例如模糊查詢 name 含 學偉 的數(shù)據(jù), 并且按 age 升序排序)
- (void)getModelsConditionSort
{
    [XWDatabase getModels:XWPerson.class sortColumn:@"age" isOrderDesc:NO condition:@"name like '%學偉'" completion:^(NSArray * _Nullable objs) {
        
    }];
}

調用 getModels 方法欣喧,傳入模型類和查詢的條件和排序的成員變量名稱

五、數(shù)據(jù)遷移

模型中成員變量發(fā)生變化益涧,動態(tài)進行數(shù)據(jù)遷移
+ (void)initialize 
+ {
    [XWDatabase updateTable:self completion:^(BOOL isSuccess) {
        
    }];

在模型對象的 initialize 方法中 調用 updateTable 方法驯鳖。之所以在 initialize 方法中調用是保證用戶無感知的情況下在操作此模型進行數(shù)據(jù)操作時自動更新。

以上就是 XWDatabase V1.0 版本的所有功能示例扭弧。謝謝记舆!

下面介紹一些使用規(guī)范和功能擴展。

六 御蒲、XWDatabaseModelProtocol 協(xié)議

/**
 主鍵 不可更改/唯一性
 
 @return 主鍵的屬性名
 */
+ (NSString *)xw_primaryKey;

/**
 聯(lián)合主鍵成員變量數(shù)組 (多個屬性共同定義主鍵) - 優(yōu)先級大于 'xw_primaryKey'

 @return 聯(lián)合主鍵成員變量數(shù)組
 */
+ (NSArray < NSString * > *)xw_unionPrimaryKey;

/**
 自定義對象映射  (key: 成員變量名稱 value: 對象類)

 @return 自定義對象映射
 */
+ (NSDictionary *)xw_customModelMapping;

/**
 忽略不保存數(shù)據(jù)庫的屬性
 
 @return 忽略的屬性名數(shù)組
 */
+ (NSSet <NSString *>*)xw_ignoreColumnNames;

/**
 自定義字段名映射表 (默認成員變量即變量名, 可自定義字段名 key: 成員變量(屬性)名稱  value: 自定義數(shù)據(jù)庫表字段名)

 @return 自定義字段名映射表
 */
+ (NSDictionary *)xw_customColumnMapping;

/**
 自定義表名 (默認屬性類名)

 @return 自定義表名
 */
+ (NSString *)xw_customTableName;

當模型遵守 XWDatabaseModelProtocol 協(xié)議并選擇性實現(xiàn)其中某些方法時她便會更好的為您服務。當然 主鍵 xw_primaryKey(或聯(lián)合主鍵 xw_unionPrimaryKey )是查詢和更新必須要實現(xiàn)的方法府瞄。

如果模型中成員變量存在其他的自定義模型碘箍,那其他的自定義模型需要遵從 NSCoding 協(xié)議并實現(xiàn) initWithCoderencodeWithCoder 方法。 XWDatabase 中的 NSObject+XWModel 提供了一個宏可以快速使自定義對象具備歸解檔的功能 XWCodingImplementation

設計思路

  1. 根據(jù) runtime 獲取對象成員變量名稱和類型生成 建表 SQL 語句
  2. 根據(jù)當前對象成員變量名稱和原有數(shù)據(jù)庫表中字段排序后進行比較货邓,有差異進行數(shù)據(jù)遷移
  3. 根據(jù)模型動態(tài)生成 SQL 語句
  4. 利用事務進行大數(shù)據(jù)量的操作
  5. 創(chuàng)建一個倍嗤В活的子線程(使異步線程的 Runloop 保持活躍)進行數(shù)據(jù)庫操作,使用主線程隊列保證數(shù)據(jù)操作的同步
  6. 數(shù)據(jù)庫底層封裝自 FMDB
  7. 創(chuàng)建一個單獨存放圖片二進制的庫存儲二進制文件复隆。真實表中存儲 二進制 文件的 hash 值已達到數(shù)據(jù)重用姆涩。

此庫支持 CocoaPod 集成:

pod 'XWDatabase'

項目源碼開源在 GitHub 中,鏈接: XWDatabase

作者:極客學偉
博客:https://blog.csdn.net/qxuewei/

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末亏栈,一起剝皮案震驚了整個濱河市宏赘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌察署,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件脐往,死亡現(xiàn)場離奇詭異扳埂,居然都是意外死亡,警方通過查閱死者的電腦和手機梅尤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來酝蜒,“玉大人矾湃,你說我怎么就攤上這事堕澄。” “怎么了蛙紫?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵坑傅,是天一觀的道長。 經(jīng)常有香客問我蒜茴,道長浆西,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任近零,我火速辦了婚禮,結果婚禮上窖杀,老公的妹妹穿的比我還像新娘裙士。我一直安慰自己,他們只是感情好痊项,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布酥诽。 她就那樣靜靜地躺著,像睡著了一般肮帐。 火紅的嫁衣襯著肌膚如雪边器。 梳的紋絲不亂的頭發(fā)上托修,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天睦刃,我揣著相機與錄音,去河邊找鬼涩拙。 笑死,一個胖子當著我的面吹牛工育,可吹牛的內容都是我干的搓彻。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼怔接,長吁一口氣:“原來是場噩夢啊……” “哼骑篙!你這毒婦竟也來了?” 一聲冷哼從身側響起靶端,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤杨名,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后台谍,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡坞生,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年是己,在試婚紗的時候發(fā)現(xiàn)自己被綠了任柜。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沛厨。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡摔认,死狀恐怖,靈堂內的尸體忽然破棺而出电谣,到底是詐尸還是另有隱情抹蚀,我是刑警寧澤辰企,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站竹观,受9級特大地震影響镐捧,放射性物質發(fā)生泄漏臭增。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一列牺、第九天 我趴在偏房一處隱蔽的房頂上張望拗窃。 院中可真熱鬧,春花似錦九默、人聲如沸宾毒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至耳峦,卻和暖如春妨退,著一層夾襖步出監(jiān)牢的瞬間蜕企,已是汗流浹背冠句。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留唇牧,地道東北人聚唐。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像扮惦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子崖蜜,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內容