正如我们前面所看到的,原生SQLite API在使用时还是比较麻烦的,于是,开源社区就出现了一系列将SQLite API进行封装的库,其中FMDB的被大多数人所使用
FMDB和SQLite相比较,SQLite比较原始,操作比较复杂,使用的是C的函数对数据库进行操作,但是SQLite可控性更强,并且能够跨平台,FMDB只能在iOS开发中使用
cocoapods导入第三方库FMDB
pod 'FMDB'
FMDB简介
FMDB是iOS开发中的一个轻量级第三方数据库框架,它以OC
的方式封装了SQLite
的C语言接口,省去了麻烦的C语言代码,且更加面向对象,操作方便
FMDB一般涉及以下3个核心类:
- FMDatabase:此类的一个实例代表一个SQLite数据库,也有许多执行SQL语句的方法
- FMResultSet(结果集):使用FMDatabase执行SQLite查询语句后的结果集
- FMDatabaseQueue(数据库队列):用于在多线程中执行多个查询或更新,它是线程安全的
FMDB基本使用
打开数据库
_dataBase = [FMDatabase databaseWithPath: @"/Users/Username/Desktop/CS/Xcode/FMDBTest/fmDb.sqlite"];
if (![_dataBase open]) {
NSLog(@"打开数据库失败!");
} else {
NSLog(@"%@", _dataBase.databasePath);
}
//其他代码
//...
[_dataBase close];
//通常打开操作完成后,需要调用close方法来关闭
- 当
fmDb.sqlite
数据库不存在时,会自动创建
- Path参数传入空字符串
@""
,会在临时目录创建一个空数据库,FMDatabase连接关闭时,数据库文件也被删除 - 传入的参数是
nil
时,会在内存中创建一个临时数据库,FMDatabase连接关闭时,数据库文件会被销毁
执行更新操作
与SQLite一样,除查询以外的所有操作,都称为“更新”,包括create
、drop
、insert
、update
、delete
等
传入的参数为SQLite语句字符串
...
表示可变数量的参数(),可以根据需要将一些额外的参数传递给方法
这里以创建表、插入数据作为示例:
BOOL result = [_dataBase executeUpdate: @"CREATE TABLE IF NOT EXISTS t_Student(ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT NOT NULL, AGE INTEGER NOT NULL, SCORE REAL)"];
if (result) {
NSLog(@"创表成功");
//插入操作
for (int i = 0; i < 10; ++i) {
NSString* name = [NSString stringWithFormat: @"jaxon-%d", arc4random_uniform(100)];
//不确定的参数用?、?占位
[_dataBase executeUpdate: @"INSERT INTO t_student (name, age) VALUES (?, ?)", name, @(arc4random_uniform(40))];
//不确定的参数用%@、%d占位
//[_dataBase executeUpdateWithFormat: @"INSERT INTO t_student (name, age) VALUES (@%, %d)", name, @(arc4random_uniform(40))];
}
//删除操作
//[_dataBase executeUpdate: @"DROP TABLE IF EXISTS t_student"];
} else {
NSLog(@"创表失败");
}
执行查询操作
只管将SQL查询语句传进去
FMResultSet* resultSet = [_dataBase executeQuery: @"SELECT * FROM t_student"];
// 遍历结果集
while ([resultSet next]) {
int ID = [resultSet intForColumn: @"ID"];
NSString* name = [resultSet stringForColumn: @"NAME"];
int age = [resultSet intForColumn: @"AGE"];
NSLog(@"%d %@ %d", ID, name, age);
}
运行结果:
可以看到插入操作也是成功的
数据参数
这里还有一些有关参数的小细节:
调用executeUpdate
方法来将SQLite语句中?
所指代的具体参数传入,通常使用变长参数来传递进去的,像这样:
NSString* sql = @"INSERT INTO t_student (name, age) VALUES (?, ?)";
[_dataBase executeUpdate: sql, name, @(arc4random_uniform(40))];
变长参数的作用体现在这里
要注意的是,参数必须是NSObject
的子类,所以如果有C风格的数据类型,应包装成OC风格才能使用:
//错误
//[_dataBase executeUpdate: @"INSERT INTO t_student VALUES (?)", 42];
//正确
[_dataBase executeUpdate: @"", [NSNumber numberWithInt: 42]];
数据库队列
FMDatabaseQueue涉及到保证线程安全,编者此时此刻并未学习有关线程相关知识,以后再加以了解
总结
FMDB对SQLite进行了良好的封装,使用起来非常方便,对于那些使用纯SQLite来进行数据库操作的项目,可以将其迁移到FMDB上,提高数据库相关功能维护的效率