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) initWithCoder 和 encodeWithCoder 方法。 XWDatabase 中的 NSObject+XWModel 提供了一個宏可以快速使自定義對象具備歸解檔的功能 XWCodingImplementation
設計思路
- 根據(jù)
runtime獲取對象成員變量名稱和類型生成 建表SQL語句 - 根據(jù)當前對象成員變量名稱和原有數(shù)據(jù)庫表中字段排序后進行比較,有差異進行數(shù)據(jù)遷移
- 根據(jù)模型動態(tài)生成
SQL語句 - 利用事務進行大數(shù)據(jù)量的操作
- 創(chuàng)建一個?;畹淖泳€程(使異步線程的
Runloop保持活躍)進行數(shù)據(jù)庫操作,使用主線程隊列保證數(shù)據(jù)操作的同步 - 數(shù)據(jù)庫底層封裝自 FMDB
- 創(chuàng)建一個單獨存放圖片二進制的庫存儲二進制文件。真實表中存儲 二進制 文件的
hash值已達到數(shù)據(jù)重用。
此庫支持 CocoaPod 集成:
pod 'XWDatabase'
項目源碼開源在 GitHub 中,鏈接: XWDatabase
作者:極客學偉
博客:https://blog.csdn.net/qxuewei/