概要
levelDB是谷歌开发的kv数据库, 其用C++编写, 使用范围较广. 目前在iOS平台上也有应用. levelDB采用了延迟写入的技术, 所以写入速度比较快. 官方数据如下:
我个人简单的写入测试了一下, 在iOS平台上同样的硬件设备,
确实比sqlite要快很多. 本文主要介绍在iOS平台上的如何使用levelDB.
编译
- 首先下载源代码
git clone https://github.com/google/leveldb.git
- 编译
cd leveldb
CXXFLAGS=-stdlib=libc++ make PLATFORM=IOS
注意, 如果系统提示权限问题, 请切换到root下或者使用sudo来执行编译命令
加入工程
编译会生成两个 .a 文件, 需要我们添加到项目工程中.
同时, 不要忘记加入头文件
注意, 这里有两个文件比较特殊: THLevelDB.h和THLeveDB.mm. 这两个文件是参考一篇博文轻量级的KV数据库LevelDB在Objective-C上的应用提供的封装.
曾静将这个封装和leveDB的头文件和编译后的.a文件进行了统合, 可以使用这个repo. 如果是cocoapods, 可以直接引入.
用法
- 取得实例
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString *pageDBPath = [docPath stringByAppendingPathComponent:@"my_leveldb.db"];
THLevelDB *myLevelDB = [THLevelDB levelDBWithPath:pageDBPath];
注意, 数据库文件必须是 *.db 的形式
- 写
NSString *key = [NSString stringWithFormat:@"%lld", a];
[myLevelDB setString:@"hello world" forKey:key];
注意, 这里key值必须是一个String
- 读
NSString *str = [myLevelDB stringForKey:@"somekey"]; //根据key取得对应值
NSArray *keys = [myLevelDB allKeys]; //取得所有的key
改变排序
levelDB提供了方法可以改变key值在数据库中的排序. 这里需要实现一个比较用的方法类, 同时在数据库实例初始化的时候加入加进去.
假设我们的key是一个long long的数值的字符串. 我们想每次加入key时, 都能有序的在数据中保存.
- 首先实现比较用的方法类
在THLevelDB.mm文件中, 添加
class TwoPartComparator : public leveldb::Comparator {
public:
// Positive
int Compare(const leveldb::Slice& a, const leveldb::Slice& b) const {
long long v1 = atoll(a.data());
long long v2 = atoll(b.data());
if (v1 < v2) return -1;
if (v1 > v2) return +1;
return 0;
}
// Ignore the following methods for now:
const char* Name() const { return "TwoPartComparator"; }
void FindShortestSeparator(std::string*, const leveldb::Slice&) const {}
void FindShortSuccessor(std::string*) const {}
};
- 在interface中增加这个比较的类的对象
@interface THLevelDB ()
{
leveldb::DB *_db;
leveldb::ReadOptions _readOptions;
leveldb::WriteOptions _writeOptions;
NSString *_path;
TwoPartComparator _cmp; //这一行是增加的
}
注意, 这一步比较关键, 因为这个方法类需要一直能够在内存中存在以便于数据库实例去调用, 所以我们必须要放在这里.
- 初始化的时候将这个方法类传入
- (id)initWithPath:(NSString *)path
{
self = [super init];
if (self)
{
_path = path;
leveldb::Options options;
options.create_if_missing = true;
options.comparator = &_cmp; //将这个方法类的实例地址传入
if (![[NSFileManager defaultManager] fileExistsAtPath:_path])
...
参考
本文主要参考了