WCDB是一個高效、完整、易用的移動數據庫框架,基於SQLCipher,支持iOS, macOS。html
易用,WCDB支持一句代碼便可將數據取出並組合爲object。git
WINQ(WCDB語言集成查詢):經過WINQ,開發者無須爲了拼接SQL的字符串而寫一大坨膠水代碼。github
ORM(Object Relational Mapping):WCDB支持靈活、易用的ORM。開發者能夠很便捷地定義表、索引、約束,並進行增刪改查操做。sql
[database getObjectsOfClass:WCTSampleConvenient.class
fromTable:tableName where:WCTSampleConvenient.intValue>=10 limit:20];
高效,WCDB經過框架層和sqlcipher源碼優化,使其更高效的表現。數據庫
多線程高併發:WCDB支持多線程讀與讀、讀與寫併發執行,寫與寫串行執行。多線程
批量寫操做性能測試:併發
更多關於WCDB的性能數據,請參考benchmark。app
完整,WCDB覆蓋了數據庫相關各類場景的所需功能。框架
經過CocoaPods安裝,此處不介紹安裝過程,感興趣能夠參考文章:http://www.cnblogs.com/HJiang/p/7228166.html高併發
/* 將一個已有的ObjC類進行ORM綁定的過程以下: 定義該類遵循WCTTableCoding協議。能夠在類聲明上定義,也能夠經過文件模版在category內定義。 使用WCDB_PROPERTY宏在頭文件聲明須要綁定到數據庫表的字段。 使用WCDB_IMPLEMENTATIO宏在類文件定義綁定到數據庫表的類。 使用WCDB_SYNTHESIZE宏在類文件定義須要綁定到數據庫表的字段。 */
新建Message類
Message.h
#import <Foundation/Foundation.h> @interface Message : NSObject /** * 本地id */ @property (nonatomic,assign) int localID; /** * 消息內容 */ @property (nonatomic, strong) NSString *content; /** * 建立時間 */ @property (nonatomic, strong) NSDate *createTime; /** * 最後更新時間 */ @property (nonatomic, strong) NSDate *modifiedTime; /** * 未讀消息 */ @property (nonatomic,assign) int unused; @end
Message.mm
#import "Message.h" #import "Message+WCTTableCoding.h" @implementation Message // 利用這個宏定義綁定到表的類 WCDB_IMPLEMENTATION(Message) // 下面四個宏定義綁定到表中的字段 WCDB_SYNTHESIZE(Message, localID) WCDB_SYNTHESIZE(Message, content) WCDB_SYNTHESIZE(Message, createTime) WCDB_SYNTHESIZE(Message, modifiedTime) // 約束宏定義數據庫的主鍵 WCDB_PRIMARY(Message, localID) // 定義數據庫的索引屬性,它直接定義createTime字段爲索引 // 同時 WCDB 會將表名 + "_index" 做爲該索引的名稱 WCDB_INDEX(Message, "_index", createTime) - (NSString *)description{ return [NSString stringWithFormat:@"localID:%d content:%@ createTime:%@ modifiedTime:%@",_localID,_content,_createTime,_modifiedTime]; } @end
Message+WCTTableCoding.h Message分類
#import "Message.h" #import <WCDB/WCDB.h> @interface Message (WCTTableCoding) <WCTTableCoding> /* 須要綁定到表中的字段在這裏聲明,在.mm中去綁定 使用WCDB_PROPERTY宏在頭文件聲明須要綁定到數據庫表的字段。 */ WCDB_PROPERTY(localID) WCDB_PROPERTY(content) WCDB_PROPERTY(createTime) WCDB_PROPERTY(modifiedTime) @end
因爲WCDB是基於Objective-C++,所以須要將引用WCDB的源文件後綴.m
改成.mm
因此Message.m需修改成.mm
WCTDatabaseManager.h WCTDatabaseManager.mm
#import <Foundation/Foundation.h> @class WCTDatabase; @interface WCTDatabaseManager : NSObject + (instancetype)shareInstance; - (WCTDatabase *)getDatabase; /** 建立數據庫 @param tableName 表名稱 @return 是否建立成功 */ - (BOOL)creatDataBaseWithName:(NSString *)tableName; @end
#import "WCTDatabaseManager.h" #import "WCTDatabaseManager+DataBase.h" #import "Message.h" //#import "Message+WCTTableCoding.h" @interface WCTDatabaseManager() { WCTDatabase *database; } @end @implementation WCTDatabaseManager + (instancetype)shareInstance{ static WCTDatabaseManager * instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[WCTDatabaseManager alloc]init]; }); return instance; } - (NSString *)getDatabasePath{ //獲取沙盒根目錄 NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; // 文件路徑 NSString *filePath = [documentsPath stringByAppendingPathComponent:@"Wechat.sqlite"]; return filePath; } - (WCTDatabase *)getDatabase{ if(!database){ NSString *filePath = [self getDatabasePath]; NSLog(@"wChatDatapath = %@",filePath); database = [[WCTDatabase alloc] initWithPath:filePath]; } return database; } -(BOOL)creatDataBaseWithName:(NSString *)tableName{ [self getDatabase]; // 數據庫加密 //NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding]; //[database setCipherKey:password]; //測試數據庫是否可以打開 if ([database canOpen]) { // WCDB大量使用延遲初始化(Lazy initialization)的方式管理對象,所以SQLite鏈接會在第一次被訪問時被打開。開發者不須要手動打開數據庫。 // 先判斷表是否是已經存在 if ([database isOpened]) { if ([database isTableExists:tableName]) { NSLog(@"表已經存在"); return NO; }else{ return [database createTableAndIndexesOfName:tableName withClass:Message.class]; } } } return NO; } @end
WCTDatabaseManager+DataBase.h WCTDatabaseManager分類,引入WCDB頭文件
#import <WCDB/WCDB.h> @interface WCTDatabaseManager (DataBase) @end
#import <Foundation/Foundation.h> @class Message; @interface MessageDao : NSObject - (BOOL)insertMessage:(Message *)message; - (BOOL)insertMessageWithTransaction:(Message *)message; - (BOOL)insertMessageWithBlock:(Message *)message; - (BOOL)deleteMessage:(Message *)message; - (BOOL)updataMessage:(Message *)message; - (NSArray *)seleteMessages; @end
#import "MessageDao.h" #import "WCTDatabaseManager.h" #import <WCDB/WCDB.h> #import "Message.h" #import "Message+WCTTableCoding.h" #define kDataBase [[WCTDatabaseManager shareInstance] getDatabase] @implementation MessageDao - (BOOL)insertMessage:(Message *)message{ return [kDataBase insertObject:message into:@"message"]; } // WCTDatabase 事務操做,利用WCTTransaction - (BOOL)insertMessageWithTransaction:(Message *)message{ BOOL ret = [kDataBase beginTransaction]; ret = [self insertMessage:message]; if (ret) { [kDataBase commitTransaction]; }else{ [kDataBase rollbackTransaction]; } return ret; } // 另外一種事務處理方法Block - (BOOL)insertMessageWithBlock:(Message *)message{ BOOL commit = [kDataBase runTransaction:^BOOL{ BOOL ret = [self insertMessage:message]; if (ret) { return YES; }else{ return NO; } } event:^(WCTTransactionEvent event) { NSLog(@"Event %d", event); }]; return commit; } - (BOOL)deleteMessage:(Message *)message{ // 刪除 //DELETE FROM message WHERE localID>0; return [kDataBase deleteObjectsFromTable:@"message" where:Message.localID > 0]; } - (BOOL)updataMessage:(Message *)message{ //修改 //UPDATE message SET content="Hello, Wechat!"; return [kDataBase updateAllRowsInTable:@"message" onProperty:Message.content withObject:message]; } - (NSArray *)seleteMessage{ //SELECT * FROM message ORDER BY localID NSArray<Message *> * message = [kDataBase getObjectsOfClass:Message.class fromTable:@"message" orderBy:Message.localID.order()]; return message; } @end
---恢復內容結束---
WCDB是一個高效、完整、易用的移動數據庫框架,基於SQLCipher,支持iOS, macOS。
易用,WCDB支持一句代碼便可將數據取出並組合爲object。
WINQ(WCDB語言集成查詢):經過WINQ,開發者無須爲了拼接SQL的字符串而寫一大坨膠水代碼。
ORM(Object Relational Mapping):WCDB支持靈活、易用的ORM。開發者能夠很便捷地定義表、索引、約束,並進行增刪改查操做。
[database getObjectsOfClass:WCTSampleConvenient.class
fromTable:tableName where:WCTSampleConvenient.intValue>=10 limit:20];
高效,WCDB經過框架層和sqlcipher源碼優化,使其更高效的表現。
多線程高併發:WCDB支持多線程讀與讀、讀與寫併發執行,寫與寫串行執行。
批量寫操做性能測試:
更多關於WCDB的性能數據,請參考benchmark。
完整,WCDB覆蓋了數據庫相關各類場景的所需功能。
經過CocoaPods安裝,此處不介紹安裝過程,感興趣能夠參考文章:http://www.cnblogs.com/HJiang/p/7228166.html
/*
將一個已有的ObjC類進行ORM綁定的過程以下:
定義該類遵循WCTTableCoding協議。能夠在類聲明上定義,也能夠經過文件模版在category內定義。
使用WCDB_PROPERTY宏在頭文件聲明須要綁定到數據庫表的字段。
使用WCDB_IMPLEMENTATIO宏在類文件定義綁定到數據庫表的類。
使用WCDB_SYNTHESIZE宏在類文件定義須要綁定到數據庫表的字段。
*/
新建Message類
Message.h
#import <Foundation/Foundation.h> @interface Message : NSObject /** * 本地id */ @property (nonatomic,assign) int localID; /** * 消息內容 */ @property (nonatomic, strong) NSString *content; /** * 建立時間 */ @property (nonatomic, strong) NSDate *createTime; /** * 最後更新時間 */ @property (nonatomic, strong) NSDate *modifiedTime; /** * 未讀消息 */ @property (nonatomic,assign) int unused; @end
Message.mm
#import "Message.h" #import "Message+WCTTableCoding.h" @implementation Message // 利用這個宏定義綁定到表的類 WCDB_IMPLEMENTATION(Message) // 下面四個宏定義綁定到表中的字段 WCDB_SYNTHESIZE(Message, localID) WCDB_SYNTHESIZE(Message, content) WCDB_SYNTHESIZE(Message, createTime) WCDB_SYNTHESIZE(Message, modifiedTime) // 約束宏定義數據庫的主鍵 WCDB_PRIMARY(Message, localID) // 定義數據庫的索引屬性,它直接定義createTime字段爲索引 // 同時 WCDB 會將表名 + "_index" 做爲該索引的名稱 WCDB_INDEX(Message, "_index", createTime) - (NSString *)description{ return [NSString stringWithFormat:@"localID:%d content:%@ createTime:%@ modifiedTime:%@",_localID,_content,_createTime,_modifiedTime]; } @end
Message+WCTTableCoding.h Message分類
#import "Message.h" #import <WCDB/WCDB.h> @interface Message (WCTTableCoding) <WCTTableCoding> /* 須要綁定到表中的字段在這裏聲明,在.mm中去綁定 使用WCDB_PROPERTY宏在頭文件聲明須要綁定到數據庫表的字段。 */ WCDB_PROPERTY(localID) WCDB_PROPERTY(content) WCDB_PROPERTY(createTime) WCDB_PROPERTY(modifiedTime) @end
因爲WCDB是基於Objective-C++,所以須要將引用WCDB的源文件後綴.m
改成.mm
因此Message.m需修改成.mm
WCTDatabaseManager.h WCTDatabaseManager.mm
#import <Foundation/Foundation.h> @class WCTDatabase; @interface WCTDatabaseManager : NSObject + (instancetype)shareInstance; - (WCTDatabase *)getDatabase; /** 建立數據庫 @param tableName 表名稱 @return 是否建立成功 */ - (BOOL)creatDataBaseWithName:(NSString *)tableName; @end
#import "WCTDatabaseManager.h" #import "WCTDatabaseManager+DataBase.h" #import "Message.h" //#import "Message+WCTTableCoding.h" @interface WCTDatabaseManager() { WCTDatabase *database; } @end @implementation WCTDatabaseManager + (instancetype)shareInstance{ static WCTDatabaseManager * instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[WCTDatabaseManager alloc]init]; }); return instance; } - (NSString *)getDatabasePath{ //獲取沙盒根目錄 NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; // 文件路徑 NSString *filePath = [documentsPath stringByAppendingPathComponent:@"Wechat.sqlite"]; return filePath; } - (WCTDatabase *)getDatabase{ if(!database){ NSString *filePath = [self getDatabasePath]; NSLog(@"wChatDatapath = %@",filePath); database = [[WCTDatabase alloc] initWithPath:filePath]; } return database; } -(BOOL)creatDataBaseWithName:(NSString *)tableName{ [self getDatabase]; // 數據庫加密 //NSData *password = [@"MyPassword" dataUsingEncoding:NSASCIIStringEncoding]; //[database setCipherKey:password]; //測試數據庫是否可以打開 if ([database canOpen]) { // WCDB大量使用延遲初始化(Lazy initialization)的方式管理對象,所以SQLite鏈接會在第一次被訪問時被打開。開發者不須要手動打開數據庫。 // 先判斷表是否是已經存在 if ([database isOpened]) { if ([database isTableExists:tableName]) { NSLog(@"表已經存在"); return NO; }else{ return [database createTableAndIndexesOfName:tableName withClass:Message.class]; } } } return NO; } @end
WCTDatabaseManager+DataBase.h WCTDatabaseManager分類,引入WCDB頭文件
#import <WCDB/WCDB.h> @interface WCTDatabaseManager (DataBase) @end
#import <Foundation/Foundation.h> @class Message; @interface MessageDao : NSObject - (BOOL)insertMessage:(Message *)message; - (BOOL)insertMessageWithTransaction:(Message *)message; - (BOOL)insertMessageWithBlock:(Message *)message; - (BOOL)deleteMessage:(Message *)message; - (BOOL)updataMessage:(Message *)message; - (NSArray *)seleteMessages; @end
#import "MessageDao.h" #import "WCTDatabaseManager.h" #import <WCDB/WCDB.h> #import "Message.h" #import "Message+WCTTableCoding.h" #define kDataBase [[WCTDatabaseManager shareInstance] getDatabase] @implementation MessageDao - (BOOL)insertMessage:(Message *)message{ return [kDataBase insertObject:message into:@"message"]; } // WCTDatabase 事務操做,利用WCTTransaction - (BOOL)insertMessageWithTransaction:(Message *)message{ BOOL ret = [kDataBase beginTransaction]; ret = [self insertMessage:message]; if (ret) { [kDataBase commitTransaction]; }else{ [kDataBase rollbackTransaction]; } return ret; } // 另外一種事務處理方法Block - (BOOL)insertMessageWithBlock:(Message *)message{ BOOL commit = [kDataBase runTransaction:^BOOL{ BOOL ret = [self insertMessage:message]; if (ret) { return YES; }else{ return NO; } } event:^(WCTTransactionEvent event) { NSLog(@"Event %d", event); }]; return commit; } - (BOOL)deleteMessage:(Message *)message{ // 刪除 //DELETE FROM message WHERE localID>0; return [kDataBase deleteObjectsFromTable:@"message" where:Message.localID > 0]; } - (BOOL)updataMessage:(Message *)message{ //修改 //UPDATE message SET content="Hello, Wechat!"; return [kDataBase updateAllRowsInTable:@"message" onProperty:Message.content withObject:message]; } - (NSArray *)seleteMessage{ //SELECT * FROM message ORDER BY localID NSArray<Message *> * message = [kDataBase getObjectsOfClass:Message.class fromTable:@"message" orderBy:Message.localID.order()]; return message; } @end
#import "ViewController.h" #import "WCTDatabaseManager.h" #import "MessageDao.h" #import "Message.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (IBAction)createDataBaseDidClick:(UIButton *)sender { BOOL result = [[WCTDatabaseManager shareInstance] creatDataBaseWithName:@"message"]; NSLog(@"%@",((result == YES)?@"建立數據庫成功":@"建立數據庫失敗")); } - (IBAction)insertBtnDidClick:(UIButton *)sender { MessageDao *messageDao = [[MessageDao alloc] init]; Message *message = [[Message alloc] init]; message.localID = 1; message.content = @"Hello, WCDB!"; message.createTime = [NSDate date]; message.modifiedTime = [NSDate date]; [messageDao insertMessageWithTransaction:message]; } - (IBAction)updateBtnDidClick:(UIButton *)sender { MessageDao *messageDao = [[MessageDao alloc] init]; Message *message = [[Message alloc] init]; message.content = @"Hello, Wechat!"; [messageDao updataMessage:message]; } - (IBAction)selectBtnDidClick:(UIButton *)sender { MessageDao *messageDao = [[MessageDao alloc] init]; NSArray *messages = [messageDao seleteMessage]; NSLog(@"%@",messages); } - (IBAction)deleteBtnDidClick:(UIButton *)sender { MessageDao *messageDao = [[MessageDao alloc] init]; [messageDao deleteMessage:nil]; } @end
更多的查詢操做後續更新.