安装
Cocoapods
- 在podfile文件中对应的target下添加
pod 'WCDB',执行pod install。 - 在需要引用WCDB的文件头添加
#import <WCDB/WCDB.h>。由于WCDB是基于Object-C++的,所以引用WCDB的文件后缀要改成.mm。
类字段绑定(ORM)
概述
ORM主要是指将Objective-C的类映射到数据库表和索引,将类的property映射到数据库表中的字段。
绑定过程:
- 遵守
WCTTableCoding协议 - 使用
WCDB_PROPERTY宏定义在头文件声明需要绑定到数据库表的字段。 - 使用
WCDB_IMPLEMENTATION宏定义在实现文件中定义需要绑定到数据库的类。 - 使用
WCDB_SYNTHESIZE宏定义在实现文件中定义需要绑定到数据库表的字段。
ORM宏
字段宏
WCDB_SYNTHESIZE(className, propertyName),直接使用propertyName作为数据库表字段名。WCDB_SYNTHESIZE_COLUMN(className, propertyName, columnName),支持自定义字段名。使用columnName作为数据库表的字段名,以替换propertyName。WCDB_SYNTHESIZE_DEFAULT(className, propertyName, defaultValue),设置默认值。defaultValue为默认值。可以为任意的C类型或NSString,NSData,NSNumber,NSNull。WCDB_SYNTHESIZE_COLUMN_DEFAULT(className, propertyName, columnName, defaultValue),为上两种情况的组合。
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface UserInfoModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, copy) NSString *userId;
@property (nonatomic, copy) NSString *nick;
@property (nonatomic, assign) double height;
@end
NS_ASSUME_NONNULL_END
#import "UserInfoModel.h"
#import <WCDB/WCDB.h>
@implementation UserInfoModel
WCDB_IMPLEMENTATION(UserInfoModel) // 将UserInfoModel类绑定到数据库
WCDB_SYNTHESIZE(UserInfoModel, userId) // userId作为数据库表字段名
WCDB_SYNTHESIZE(UserInfoModel, name) // name作为数据库表字段名
WCDB_SYNTHESIZE_COLUMN(UserInfoModel, age, "replaceAge") // 使用replaceAge作为数据库表字段名
WCDB_SYNTHESIZE_DEFAULT(UserInfoModel, nick, @"default nick") // 使用nick作为数据库表字段名,并且默认值为default nick
WCDB_SYNTHESIZE_COLUMN_DEFAULT(UserInfoModel, height, "replaceHeight", 195) // 使用replaceHeight作为数据库表字段名,并且默认值为195
@end
创建数据库
完成类的定义后,只需要调用createTableAndIndexesOfName:withClass:即可完成数据库表的创建。
WCTDatabase *database = [[WCTDatabase alloc] initWithPath:mngr.dbPath];
BOOL ret = [database createTableAndIndexesOfName:TABLE_USER withClass:UserInfoModel.class];
数据库表结构如下:

约束宏
约束宏包括字段约束和表约束
字段约束
-
主键约束
WCDB_PRIMARY(className, propertyName)定义主键,直接使用propertyName作为数据库表的主键。
WCDB_PRIMARY_ASC(className, propertyName),主键升序。
WCDB_PRIMARY_DESC(className, propertyName),主键降序。
WCDB_PRIMARY_AUTO_INCREMENT(className, propertyName),定义主键自增。WCDB_PRIMARY_ASC_AUTO_INCREMENT(className, propertyName),主键自增和升序的组合。
注意:
实现主键自增时,需要在插入数据之前设置关联类对象的model.isAutoIncrement = YES;
-
非空约束
WCDB_NOT_NULL(className, propertyName),当该字段插入数据为空时,数据库会报错。 -
唯一约束
WCDB_UNIQUE(className, propertyName),当该字段插入数据与其他行冲突时,数据库会报错。
表约束
-
多主键约束
多主键约束以
WCDB_MULTI_PRIMARY开头,定义了数据库的多主键,支持自定义每个主键的排序方式。WCDB_MULTI_PRIMARY(className, constraintName, propertyName),多个主键通过constraintName匹配
WCDB_MULTI_PRIMARY_ASC(className, constraintName, propertyName),定义多主键,propertyName主键升序。
WCDB_MULTI_PRIMARY_DESC(className, constraintName, propertyName),定义多主键,propertyName主键降序。/** 主键为userId和age,age主键升序 */ WCDB_MULTI_PRIMARY(UserInfoModel, "_oxfff", userId) WCDB_MULTI_PRIMARY_ASC(UserInfoModel, "_oxfff", age) -
多主键唯一约束
多字段唯一约束以
WCDB_MULTI_UNIQUE开头,定义了数据库的多字段组合唯一,支持自定义每个字段的排序方式。
WCDB_MULTI_UNIQUE(className, constraintName, propertyName),多字段唯一约束。
WCDB_MULTI_UNIQUE_ASC(className, constraintName, propertyName),多字段唯一约束,propertyName对应的字段升序。WCDB_MULTI_UNIQUE_DESC(className, constraintName, propertyName),多字段唯一约束,propertyName对应的字段降序。/** 主键为userId和age唯一,age对应的字段升序 */ WCDB_MULTI_UNIQUE(UserInfoModel, "_oxfff", userId) WCDB_MULTI_UNIQUE_ASC(UserInfoModel, "_oxfff", age)
类型
SQLite数据库支持整型,浮点数,字符串,二进制数据等类型。WCDB的ORM会自动识别属性的类型并映射到合适的数据库类型。
| C类型 | 数据库类型 |
|---|---|
| 整型 | 整型(INTEGER) |
| 枚举型 | 整型(INTEGER) |
| 浮点数 | 浮点型(REAL) |
字符串(const char *的C字符串类型) |
字符串(TEXT) |
| Object-C类型 | 数据库类型 |
|---|---|
NSDate |
整型(INTEGER) |
NSNumber |
浮点型(REAL) |
NSString |
字符串(TEXT) |
其他所有符合NSCoding协议的NSObject子类 |
二进制(BLOB) |
关联的类属性中引用别的类时,需要引用到的类遵守并实现
NSCoding协议。在数据库中字段类型为二进制类型。
自定义类型
WCDB支持自定义绑定类型。类只需要实现WCTColumnCoding协议,就可以实现绑定。
@protocol WCTColumnCoding
@required
+ (instancetype)unarchiveWithWCTValue:(WCTValue *)value; //value could be nil
- (id /* WCTValue* */)archivedWCTValue; //value could be nil
+ (WCTColumnType)columnTypeForWCDB;
@end
可以使用WCDB官方提供的Xcode文件模板创建,也可以自行实现。
@interface Dog : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) NSInteger age;
@end
#import "Dog.h"
#import <WCDB/WCDB.h>
#import <YYModel/YYModel.h>
@interface Dog()<WCTColumnCoding>
@end
@implementation Dog
- (id)archivedWCTValue {
return [self yy_modelToJSONString];
}
+ (WCTColumnType)columnTypeForWCDB {
return WCTColumnTypeString; // 类型为String
}
+ (instancetype)unarchiveWithWCTValue:(WCTValue *)value {
return value ? [Dog yy_modelWithJSON:value] : nil;
}
WCTColumnType
typedef NS_ENUM(int, WCTColumnType) {
WCTColumnTypeInteger32 = (WCTColumnType) WCDB::ColumnType::Integer32,
WCTColumnTypeInteger64 = (WCTColumnType) WCDB::ColumnType::Integer64,
WCTColumnTypeDouble = (WCTColumnType) WCDB::ColumnType::Float,
WCTColumnTypeString = (WCTColumnType) WCDB::ColumnType::Text,
WCTColumnTypeBinary = (WCTColumnType) WCDB::ColumnType::BLOB,
WCTColumnTypeNil = (WCTColumnType) WCDB::ColumnType::Null,
};
WCDB内置对部分常用Object-C类型(如NSData,NSDate等)的支持。如果想自己定义基本类型,可以将内置的绑定关闭。关闭方法为:删除工程文件的Build Settings->Preprocessor Macros下各个scheme的WCDB_BUILTIN_COLUMN_CODING宏。
修改字段
SQLite支持增加,不支持删除、重命名字段。
增加字段
只需要在定义处添加WCDB_SYNTHESIZE(className, propertyName),然后重新执行createTableAndIndexesOfName:withClass:即可。
删除字段
只需将要删除的字段的定义删除即可。
这里只是忽略这个字段,数据库表中旧的数据依然会存在。
重命名字段
使用WCDB_SYNTHESIZE_COLUMN(className, propertyName, columnName) 重新映射。
这里相当于在数据库表中添加一个新的字段。
其他注意事项
修改类的属性名时,需要重新映射。