文章目录WCDB入门使用准备与配置模型定义与ORM绑定WCDB 执行CRUD (增删改查)数据库的初始化和表的创建插入数据查询数据更新数据删除数据WCDB入门使用WCDB 是微信团队开源的一个高效、完整、易用的移动端数据库框架它基于 SQLite 和 SQLCipher支持 C、Java、Kotlin、Swift 和 Objective-C 等多种语言WCDB通过两个核心设计能用面向对象的方式操作数据库把复杂的 SQL 语句变成一行简单的代码。准备与配置在开始写代码前需要先完成两件事因为我们只使用OC,所以导入WCDB的objc部分集成WCDB在Podfile中添加pod WCDB.objc然后运行pod install。关键步骤文件改名因为WCDB是用Objective-C编写的所有需要引入或使用WCDB的.m文件都必须把后缀名改为.mm模型定义与ORM绑定ORM (Object Relational Mapping) 是WCDB的核心它能把Objective-C的类和数据库的表、字段一一对应起来。这样就不用写SQL来建表了。导入WCDB之后就可以直接按照按照模版创建一个WCDB的使用文档了, 创建新文件,在iOS标签下会出现WCDB模块,点击中间的TableCodable,输入文件名可以生成模版文件了WCDB模型ORM绑定在WCDB内ORMObject Relational Mapping是指将一个ObjC的类映射到数据库的表和索引将类的property映射到数据库表的字段这一过程。通过ORM可以达到直接通过Object进行数据库操作省去拼装过程的目的。在MyWCDB.h 文件中声明需要存入数据库的属性// MyWCDB.hinterfaceMyWCDB:NSObject/* // An ORM type can be any C types or any ObjC classes which conforms to NSCoding or WCTColumnCoding protocol. // An ORM property must contains a setter which can be private property (nonatomic, retain) NSString *#property1#; property (nonatomic, assign) NSInteger #property2#; property (nonatomic, assign) float #property3#; property (nonatomic, strong) NSArray *#property4#; property (nonatomic, readonly) NSDate *#..........#; */property(nonatomic,assign)NSInteger userID;property(nonatomic,strong)NSString*name;property(nonatomic,strong)NSArray*array;end在MyWCDBWCTTableCoding.h中用WCDB_PROPERTY声明注意这些宏只负责声明它们不负责执行。具体的执行工作是在MyWCDB.mm文件中通过WCDB_IMPLEMENTATION和WCDB_SYNTHESIZE等宏来完成的。为什么要分成两个文件这是 WCDB 设计的一种良好实践通过Category类别来隔离数据库相关的代码。优点这种设计可以保持主模型类MyWCDB.h干净、纯粹不被数据库特定的代码所污染。如果有一天你不想用 WCDB 了或者要换一种持久化方案只需要处理这个 Category 文件而不用去改动MyWCDB.h的核心业务逻辑。// MyWCDBWCTTableCoding.h#importMyWCDB.h#importWCDBObjc/WCDBObjc.hinterfaceMyWCDB(WCTTableCoding)WCTTableCoding/* WCDB_PROPERTY(#property1#) WCDB_PROPERTY(#property2#) WCDB_PROPERTY(#property3#) WCDB_PROPERTY(#property4#) WCDB_PROPERTY(#.........#) */WCDB_PROPERTY(userID)WCDB_PROPERTY(name)WCDB_PROPERTY(array)end在MyWCDB.mm中用WCDB_SYNTHESIZE实现绑定// MyWCDB.mm#importMyWCDBWCTTableCoding.h#importMyWCDB.himplementationMyWCDBWCDB_IMPLEMENTATION(MyWCDB)WCDB_SYNTHESIZE(text)WCDB_SYNTHESIZE(array)WCDB_SYNTHESIZE(myId)//// 自定义列名//WCDB_SYNTHESIZE_COLUMN(#property5#, #column name#) // Custom column name// 主键, 每次插入新纪录是自动加一WCDB_PRIMARY_AUTO_INCREMENT(myId)// 数据库索引// 为指定创建索引, 用于加速查询速度//WCDB_INDEX(#_index_subfix#, #property#)end这段代码是WCDB for Objective-C 进行对象关系映射ORM的核心配置。它的作用就是告诉 WCDB 如何将MyWCDB类与数据库中的一张表对应起来。WCDB_IMPLEMENTATION(MyWCDB)作用这是绑定的“开关”。它是一个必需的宏用来为MyWCDB类初始化 ORM 所需的内部结构。没有这行代码后面的所有绑定宏都不会生效。WCDB_SYNTHESIZE(userID)作用: 将MyWCDB类的userID属性绑定到数据库表中一个同名的列上。当在代码里写入myWCDBObject.userID 10并保存时WCDB 就知道要把值10存到表里的userID这一列。同理WCDB_SYNTHESIZE(name)和WCDB_SYNTHESIZE(array)就是将name和array属性也绑定到对应的列。定制化配置WCDB_SYNTHESIZE_COLUMN(#property5#, #column name#)作用用于自定义数据库中的列名。当不想用属性名作为列名时就可以用它。比如 OC 属性叫userID但想在数据库里把它命名为id就可以写成WCDB_SYNTHESIZE_COLUMN(id, userID)。高级约束作用将userID列设置为自增主键。userID将成为这张表的主键确保每行数据的唯一每次插入一个新对象时只要不手动设置userIDWCDB 就会自动为它分配一个全局唯一的、递增的整数值1, 2, 3…。这是建立数据关系如用户ID关联订单的基础。WCDB_INDEX(#_index_subfix#, #property#)作用为指定的属性列创建索引。想象一下一本书的“索引”章节。如果你经常根据name字段来查询用户那么为name列建立索引可以极大地提升查询速度尤其是在数据量很大时。#_index_subfix#是你这个索引起的一个后缀名WCDB 会自动生成完整的索引名比如表名加后缀。执行CRUD (增删改查)首先,需要将所有需要引入或使用WCDB的.m文件都必须把后缀名改为.mm, 例如: 将ViewController.m改为ViewController.mm, 然后, 在其中完成数据库的初始化和表的创建, 这是所有操作的基础数据库的初始化和表的创建// ViewController.mm#importViewController.h#importMyWCDBWCTTableCoding.h// 导入 Category 才能让 WCDB 识别 MyWCDBinterfaceViewController()// 声明数据库property(nonatomic,strong)WCTDatabase*database;endimplementationViewController-(void)viewDidLoad{[superviewDidLoad];// Do any additional setup after loading the view.[selfsetUpDatabase];[selfcreateTable];}-(void)setUpDatabase{// 获取数据库文件路径NSString*docPath[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask,YES)firstObject];NSString*dbPath[docPath stringByAppendingPathComponent:myTest.db];NSLog(数据库路径: %,dbPath);// 创建数据库实例self.database[[WCTDatabase alloc]initWithPath:dbPath];// 打开数据库如果打开失败会抛出异常// WCDB 会第一次执行增删改查时自动打开数据库不需要手动调用open。// 可以用 canOpen 检测数据库文件是否可以正常初始化isOpened 判断是否已经打开。if(![self.database canOpen]){NSLog(数据库打开失败);return;}NSLog(数据库打开成功);}-(void)createTable{// 创建表表名使用类名 MyWCDBBOOL result[self.database createTable:MyWCDBwithClass:MyWCDB.class];if(result){NSLog(表创建成功);}else{NSLog(表创建失败);}}end获取Documents 目录路径NSString* docPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];作用获取应用的 Documents 目录路径参数说明NSDocumentDirectory指定要查找 Documents 目录NSUserDomainMask指定用户域应用沙盒YES是否展开波浪号路径~返回值路径数组通过firstObject获取第一个也是唯一一个路径拼接完整的数据库文件路径NSString* dbPath [docPath stringByAppendingPathComponent: myTest.db];作用在 Documents 目录下创建一个名为myTest.db的数据库文件参数说明myTest.db数据库文件名可以自定义建议以.db或.sqlite结尾示例:/Users/.../Documents/myTest.db创建数据库实例self.database [[WCTDatabase alloc] initWithPath: dbPath]; 此时数据库并没有真正打开 ,只是创建了对象 如果路径目录不存在 ,WCDB会尝试自动创建检测数据库是否可用if(![self.database canOpen]){NSLog(数据库打开失败);return;}验证数据库文件是否可以被正确初始化和打开WCDB 会第一次执行增删改查时自动打开数据库, 可以用 canOpen 检测数据库文件是否可以正常初始化isOpened 判断是否已经打开。插入数据// insert Data-(void)insertData{// 创建一个用户MyWCDB*user1[[MyWCDB alloc]init];user1.name张三;user1.array[iOS,Python];BOOL success1[self.database insertObject:user1 intoTable:MyWCDB];if(success1){NSLog(数据插入成功, user1: %lu, %, %,user1.userID,user1.name,user1.array);}MyWCDB*user2[[MyWCDB alloc]init];user2.name张三;user2.array[iOS,Python];BOOL success2[self.database insertObject:user2 intoTable:MyWCDB];if(success2){NSLog(数据插入成功, user2: %lu, %, %,user2.userID,user2.name,user2.array);}}查询数据// search Data-(void)queryData{// 查询所有数据NSArrayMyWCDB**results[self.database getObjectsOfClass:MyWCDB.class fromTable:MyWCDB];NSLog(查询到%ld条数据,results.count);for(MyWCDB*iteminresults){NSLog(userID: %lu, name: %, array: %,item.userID,item.name,item.array);}}更新数据-(void)updateData{// 将 userID 为 1 的用户改为 王五BOOL success[self.database updateTable:MyWCDBsetProperty:MyWCDB.name toValue:王五where:MyWCDB.userID1];if(success){printf(success);}else{NSLog(fail);}[selfqueryData];}删除数据-(void)deleteData{// 删除 userID 为2 的用户BOOL success[self.database deleteFromTable:MyWCDB];if(success){NSLog(delete success);}else{NSLog(delete failure);}[selfqueryData];}
