WCDB

WCDB是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS。

WCDB for iOS/macOS

基本特性

  • 易用,WCDB支持一句代码即可将数据取出并组合为object。

    • WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码。

    • ORM(Object Relational Mapping):WCDB支持灵活、易用的ORM。开发者可以很便捷地定义表、索引、约束,并进行增删改查操作。

      [database getObjectsOfClass:WCTSampleConvenient.classfromTable:tableNamewhere:WCTSampleConvenient.intValue>=10limit:20];

  • 高效,WCDB通过框架层和sqlcipher源码优化,使其更高效的表现。

    • 多线程高并发:WCDB支持多线程读与读、读与写并发执行,写与写串行执行。

    • 批量写操作性能测试:

      更多关于WCDB的性能数据,请参考benchmark。

  • 完整,WCDB覆盖了数据库相关各种场景的所需功能。

    • 加密:WCDB提供基于SQLCipher的数据库加密。
    • 损坏修复:WCDB内建了Repair Kit用于修复损坏的数据库。
    • 反注入:WCDB内建了对SQL注入的保护。

基本要求

  • WCDB支持iOS 7、macOS 10.9以上。
  • WCDB需使用Xcode 8.0以上版本进行编译。
  • 需使用Objective-C++。

通过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 localIDNSArray<Message *> * message = [kDataBase getObjectsOfClass:Message.class fromTable:@"message" orderBy:Message.localID.order()];return message;
}@end

测试方法

---恢复内容结束---

WCDB

WCDB是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS。

WCDB for iOS/macOS

基本特性

  • 易用,WCDB支持一句代码即可将数据取出并组合为object。

    • WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码。

    • ORM(Object Relational Mapping):WCDB支持灵活、易用的ORM。开发者可以很便捷地定义表、索引、约束,并进行增删改查操作。

      [database getObjectsOfClass:WCTSampleConvenient.classfromTable:tableNamewhere:WCTSampleConvenient.intValue>=10limit:20];

  • 高效,WCDB通过框架层和sqlcipher源码优化,使其更高效的表现。

    • 多线程高并发:WCDB支持多线程读与读、读与写并发执行,写与写串行执行。

    • 批量写操作性能测试:

      更多关于WCDB的性能数据,请参考benchmark。

  • 完整,WCDB覆盖了数据库相关各种场景的所需功能。

    • 加密:WCDB提供基于SQLCipher的数据库加密。
    • 损坏修复:WCDB内建了Repair Kit用于修复损坏的数据库。
    • 反注入:WCDB内建了对SQL注入的保护。

基本要求

  • WCDB支持iOS 7、macOS 10.9以上。
  • WCDB需使用Xcode 8.0以上版本进行编译。
  • 需使用Objective-C++。

通过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 localIDNSArray<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

更多的查询操作后续更新.

转载于:https://www.cnblogs.com/HJiang/p/8260628.html

微信数据存储WCDB for iOS/macOS相关推荐

  1. 微信数据导出。(IOS 无加密)

    code:https://github.com/Sunmile/study_note 我的代码笔记中 MMsaver exe:http://download.csdn.net/detail/oadam ...

  2. python 埋点 库_埋点全解 10 :数据存储

    1.原理概述 为了最大限度的保证事件数据的准确性.完整性和及时性,数据采集 SDK 需要及时的将事件数据同步到服务端.但在某些 特殊情况下,比如手机处于断网环境,或者根据实际需求只能在 Wi-Fi 环 ...

  3. IOS数据存储 之WCDB (一)

    IOS数据存储 之WCDB (一) 1. WCDB 简介 1.1 使用WCDB框架3大优势 1.2 WCDB 的一些基础概念 1.2.1 类字段绑定(ORM) 1.2.2 WINQ(WCDB语言集成查 ...

  4. IOS数据存储 之WCDB (二)WCDB.swift使用篇

    IOS数据存储 之WCDB (二)WCDB.swift使用篇 1.WCDB.Swfit基础使用 1.1 WCDB.Swfit 简介 1.1.1 模型绑定 1.1.2 创建数据库与表 1.1.3 操作数 ...

  5. iOS开发 数据存储之WCDB的介绍

    一.介绍 WCDB是一个高效.完整.易用的移动数据库框架,基于SQLCipher,支持iOS,macOS和Android 二.基本特性 易用,WCDB支持一句代码即可将数据取出并组合为object W ...

  6. iOS开发之数据存储

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  7. Unity 之 转微信小游戏本地数据存储方法分享

    Unity 之 转微信小游戏本地数据存储 问题背景 微信小游戏读写本地文件 WebGL平台的一些限制 报错查看方法分享 问题背景 近期在将Unity转换为小游戏的时候发现在读写本地文件的时候,使用Ap ...

  8. IOS数据存储之文件沙盒存储

    前言: 之前学习了数据存储的NSUserDefaults,归档和解档,对于项目开发中如果要存储一些文件,比如图片,音频,视频等文件的时候就需要用到文件存储了.文件沙盒存储主要存储非机密数据,大的数据. ...

  9. iOS网络编程-iCloud键值数据存储编程实例

    iCloud键值数据存储设计 iCloud键值数据存储编程实例,画面中有两个开关控件,左图是设备1点击"设置iCloud数据"按钮,将控件状态保存到iCloud服务器.右图是设备2 ...

最新文章

  1. SpringBoot + Redis:模拟 10w 人的秒杀抢单!
  2. C++中getline()函数
  3. 通过命令行方式批量设置保留IP地址的代码
  4. linux字符设备文件的打开操作,Linux字符设备驱动模型之字符设备初始化
  5. 语音识别中强制对齐_语音识别中的标注问题和嵌入式训练
  6. 【Java多线程编程】选号程序
  7. 怎么避免后台被搜索_复星保德信人寿保险有限公司星满意重大疾病保险怎么样?好不好?可信/靠谱吗?有什么优缺点/注意事项?值不值得买?一年多少钱?...
  8. winfrom实现简单计算器V2版本
  9. js获取cookie获取不到问题 vue获取cookie以及获取不到问题
  10. C# Types Type Members
  11. GUI Design Studio 4 5 151 0原型设计工具的使用
  12. 雷军100亿押注IoT,小米借AI两翼齐飞
  13. magento 安装出错 完全解决方案
  14. WP8开发日志(3):MVC设计模式进阶——绑定多个数据集
  15. load data infile 补充
  16. LINUX的awk和sed的常用用法 正则表达式 grep egrep用法
  17. bandicam安装注册
  18. lack名词形式_lack是什么意思_lack的翻译_音标_读音_用法_例句_爱词霸在线词典
  19. 什么是高中物理?一篇长长长长文告诉你!
  20. 利用子集构造法实现NFA到DFA的转换

热门文章

  1. 一文看懂国内人工智能行业产业链全景(必收藏)
  2. 红米10a和12c哪个好 红米10a和红米12c区别
  3. 随心所欲b超工作站图像处理_第七讲随心所欲版医学影像工作站软件每周一题...
  4. 《苏菲的世界》读书笔记之一:自然派哲学家
  5. couldn‘t find “libijkffmpeg.so“
  6. linux 内核 mtd读取,linux内核 mtd分区
  7. AURIX TriCore学习笔记四:LwIP裸机移植
  8. Tableau-热力图
  9. MFC架构之CWnd类
  10. ubuntu怎么连网线上网_安装完ubuntu 16.04连接网线无法上网解决