iOS - 最易用的資料庫工具類 XWDatabase 開源

極客學偉發表於2018-12-14

iOS - 最易用的資料庫工具類 XWDatabase 開源

XWDatabase GitHub 地址:github.com/qxuewei/XWD…

XWDatabase 的亮點

  • 將資料庫操作簡化到難以想象的程度,你甚至不需要知道資料庫的存在,當然更不需要寫 SQL 語句,你只需要直接操作模型即可對模型進行增刪改查的操作,她會根據模型動態在資料庫中建立以當前模型類名為名稱的資料庫表,當然你也可以自定義表名;
  • 她會根據模型的成員變數和成員變數的型別動態進行欄位的設計,有多少成員變數,表中自然就會有多少欄位與其對應,當然,你也可以忽略其中的某些你不想儲存的成員變數,也可以自定義欄位的名稱;
  • 如果哪天模型的欄位變化了,她會自動進行表中原有欄位的更新,而且無論原表中有多少資料,都會一條不落的遷移到新表中;
  • 她的API簡單到只有一行程式碼,你無需關注資料庫的開啟和關閉,一行程式碼實現增刪改查和資料遷移;
  • 你甚至可以在任何執行緒中呼叫她的API,她一定是執行緒安全的,不會出現多執行緒訪問同一個資料庫和死鎖的問題;
  • 資料操作是耗時操作,所以你無需手動開啟非同步執行緒運算元據庫操作,她會統一在一個保活的非同步執行緒中執行;
  • 她支援儲存常見的資料型別(int、long、signed、float、double、NSInteger、CGFloat、BOOL、NSString、NSMutableString、NSNumber、NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSData、NSMutableData、UIImage、NSDate、NSURL、NSRange、CGRect、CGSize、CGPoint、自定義物件等的儲存);
  • 她還對二進位制檔案的儲存做了優化,比如同一張圖片表中所有資料都持有這張圖片物件,她在資料庫中只會有一份拷貝,竭盡她所能優化儲存空間。

筆鋒一轉,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"; /// 指定想刪除的主鍵(或聯合主鍵)
    [XWDatabase deleteModel:person completion:^(BOOL isSuccess) {
        
    }];
}
複製程式碼

例項化一個物件,為主鍵賦值(得知道刪的是哪個,讓她猜,臣妾做不到), 呼叫 deleteModel 方法。

2.刪除此模型儲存的所有資料
- (void)clearModel
{
    [XWDatabase clearModel:XWPerson.class completion:^(BOOL isSuccess) {

    }];
}
複製程式碼

呼叫 clearModel 方法,傳入想刪除的模型類

3.選擇性刪除此模型儲存的資料
/// 刪除 age > 50 的資料
- (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.更新某模型所有資料 (全量更新)
/// 根據傳入的模型整體更新
- (void)updateModel
{
    XWPerson *person = [XWPerson new];
    person.cardID = @"2";
    person.name = @"新名字";
    person.girls = @[@"小妹",@"校花",@"小baby"];
    
    /// 整個模型更新
    [XWDatabase saveModel:person completion:^(BOOL isSuccess) {
        
    }];
    
}
複製程式碼

例項化一個物件, 呼叫 updateModel 方法,傳入想更新的模型。

四、查

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

例項化一個物件,為主鍵賦值, 呼叫 getModel 方法。

2.查詢資料庫中所有該模型儲存的資料
- (void)getModels
{
    [XWDatabase getModels:XWPerson.class completion:^(NSArray * _Nullable objs) {
        
        
    }];
}
複製程式碼

呼叫 getModels 方法,傳入模型類

3.查詢資料庫中所有該模型儲存的資料 - 按某成員變數排序
/// 獲取資料庫中所有該模型儲存的資料 - 按 age 欄位降序排列
- (void)getModelsSortAge
{
    [XWDatabase getModels:XWPerson.class sortColumn:@"age" isOrderDesc:YES completion:^(NSArray * _Nullable objs) {
        
    }];
}
複製程式碼

呼叫 getModels 方法,傳入模型類和要排序的欄位

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

呼叫 getModels 方法,傳入模型類和查詢的條件

5.查詢資料庫中所有該模型儲存的資料 - 自定義查詢條件並且可按照某欄位排序
/// 獲取資料庫中所有該模型儲存的資料 - 自定義查詢條件可排序 (例如模糊查詢 name 含 學偉 的資料, 並且按 age 升序排序)
- (void)getModelsConditionSort
{
    [XWDatabase getModels:XWPerson.class sortColumn:@"age" isOrderDesc:NO condition:@"name like '%學偉'" completion:^(NSArray * _Nullable objs) {
        
    }];
}
複製程式碼

呼叫 getModels 方法,傳入模型類和查詢的條件和排序的成員變數名稱

五、資料遷移

模型中成員變數發生變化,動態進行資料遷移
+ (void)initialize 
+ {
    [XWDatabase updateTable:self completion:^(BOOL isSuccess) {
        
    }];
複製程式碼

在模型物件的 initialize 方法中 呼叫 updateTable 方法。之所以在 initialize 方法中呼叫是保證使用者無感知的情況下在操作此模型進行資料操作時自動更新。

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

下面介紹一些使用規範和功能擴充套件。

六 、XWDatabaseModelProtocol 協議

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

/**
 聯合主鍵成員變數陣列 (多個屬性共同定義主鍵) - 優先順序大於 'xw_primaryKey'

 @return 聯合主鍵成員變數陣列
 */
+ (NSArray < NSString * > *)xw_unionPrimaryKey;

/**
 自定義物件對映  (key: 成員變數名稱 value: 物件類)

 @return 自定義物件對映
 */
+ (NSDictionary *)xw_customModelMapping;

/**
 忽略不儲存資料庫的屬性
 
 @return 忽略的屬性名陣列
 */
+ (NSSet <NSString *>*)xw_ignoreColumnNames;

/**
 自定義欄位名對映表 (預設成員變數即變數名, 可自定義欄位名 key: 成員變數(屬性)名稱  value: 自定義資料庫表欄位名)

 @return 自定義欄位名對映表
 */
+ (NSDictionary *)xw_customColumnMapping;

/**
 自定義表名 (預設屬性類名)

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

複製程式碼

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

如果模型中成員變數存在其他的自定義模型,那其他的自定義模型需要遵從 NSCoding 協議並實現 initWithCoderencodeWithCoder 方法。 XWDatabase 中的 NSObject+XWModel 提供了一個巨集可以快速使自定義物件具備歸解檔的功能 XWCodingImplementation

設計思路

  1. 根據 runtime 獲取物件成員變數名稱和型別生成 建表 SQL 語句
  2. 根據當前物件成員變數名稱和原有資料庫表中欄位排序後進行比較,有差異進行資料遷移
  3. 根據模型動態生成 SQL 語句
  4. 利用事務進行大資料量的操作
  5. 建立一個保活的子執行緒(使非同步執行緒的 Runloop 保持活躍)進行資料庫操作,使用主執行緒佇列保證資料操作的同步
  6. 資料庫底層封裝自 FMDB
  7. 建立一個單獨存放圖片二進位制的庫儲存二進位制檔案。真實表中儲存 二進位制 檔案的 hash 值已達到資料重用。

此庫支援 CocoaPod 整合:

pod 'XWDatabase'
複製程式碼

專案原始碼開源在 GitHub 中,連結: XWDatabase

作者:極客學偉 部落格:blog.csdn.net/qxuewei/

相關文章