上篇文章讲解了Sqlite但是sql书写起来比较麻烦,尤其是其它语言转过来的程序员会感觉吃力,于是,就出现了一系列将SQLite API进行封装的库,例如FMDB、 PlausibleDatabase、SQLitepersistentobjects等, FMDB是一款简洁、易用的封装库,这一篇文章简单介绍下FMDB的使用。
一. FMDB的优点:
1.使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
2.对比苹果自带的Core Data框架,更加轻量级和灵活
3.提供了多线程安全的数据库操作方法,有效地防止数据混乱
二、核心类
FMDB有三个主要的类
(1)FMDatabase
一个FMDatabase对象就代表一个单独的SQLite数据库
用来执行SQL语句
(2)FMResultSet
使用FMDatabase执行查询后的结果集
(3)FMDatabaseQueue
用于在多线程中执行多个查询或更新,它是线程安全的
三.FMDB的下载地址 https://github.com/ccgus/fmdb
在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖。
四. 操作
1.数据库创建
FMDatabase 是通过一个 SQLite 数据库文件路径创建的,此路径可以是以下三者之一:
一个文件的系统路径。磁盘中可以不存在此文件,因为如果不存在会自动为你创建。
一个空的字符串 @”“。会在临时位置创建一个空的数据库,当 FMDatabase 连接关闭时,该数据库会被删除。
NULL。会在内存中创建一个数据库,当 FMDatabase 连接关闭时,该数据库会被销毁。
// 创建数据库示例
FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];
打开数据库
数据库必须是打开状态,才能与之交互。如果没有足够的资源和权限来打开\创建数据库,数据库会打开失败。
数据库更新
SQL 语句中除 SELECT 语句都可以称之为更新操作。包括 CREATE,UPDATE,INSERT,ALTER,COMMIT,BEGIN,DETACH,DROP,END,EXPLAIN,VACUUM,REPLACE 等。一般只要不是以 SELECT 开头的 SQL 语句,都是更新语句。
执行更新语句后会返回一个 BOOL 值,返回 YES 表示执行更新语句成功,返回 NO 表示出现错误,可以通过调用 -lastErrorMessage 和 -lastErrorCode 方法获取更多错误信息。
数据库查询
通过调用 -executeQuery… 方法之一执行 SELECT 语句进行数据库查询操作。
执行查询操作后,如果成功会返回一个 FMResultSet 对象,反之会返回 nil。通过 -lastErrorMessage 和 -lastErrorCode 方法可以确定为什么会查询失败。
为了遍历查询结果,需要 while() 循环,然后逐条记录查看。在 FMDB 中,可以通过下面的简单方式实现:
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
// 每条记录的检索值
}
即使只需要获取一个数据,也还是必须在访问查询结果前调用 -[FMResultSet next]。
// 示例
FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
int totalCount = [s intForColumnIndex:0];
}
FMResultSet 提供了很多方便的方法来查询数据:
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumn:
objectForColumn:
这些方法都有一个 {type}ForColumnIndex: 变体,是基于列的位置来查询数据。
通常情况下,一个 FMResultSet 没有必要手动 -close,因为结果集合 (result set) 被释放或者源数据库关闭会自动关闭。
关闭数据库
当对数据库进行查询和更新操作完成后,需要调用 -close 关闭数据库 FMDatabase 的连接。
// 示例
[db close];
五.代码示例:
#pragma mark - 修改数据
-(void)testUpdateData
{
//实例: 重置密码 为 123456
NSString *username = @"asan";
NSString *newPassword = @"123456";
NSString *sql = @"UPDATE studentInfo SET password = ? WHERE username = ?";
BOOL b = [_databse executeUpdate:sql,newPassword,username];
NSLog(@"UPDATE b = %d",b);
}
#pragma mark - 删除数据
-(void)testDeleteData
{
//实例: 删除pangzi这条数据
NSString *username = @"pangzi";
NSString *sql = @"DELETE FROM studentInfo WHERE username = ?";
BOOL b = [_databse executeUpdate:sql,username];
NSLog(@"DELETE b = %d",b);
}
#pragma mark - 查询数据
-(void)testQueryData
{
//查询所有数据, 显示所有数据
NSString *sql = @"SELECT * FROM studentInfo";
//执行查询语句
//注意: 查询完之后返回一个结果集
// 结果集: 立即为二维数组, EXCEL表格
FMResultSet *resultSet = [_databse executeQuery:sql];
//注意: 取得每一行使用[resultSet next];
// 取到一行返回YES, 最后一行取完之后在执行返回NO
while ([resultSet next]) {
//第一行数据: 1 asan 1314 58
int sid = [resultSet intForColumn:@"sid"];
NSString *name = [resultSet stringForColumn:@"username"];
NSString *password = [resultSet stringForColumn:@"password"];
int score = [resultSet intForColumn:@"score"];
NSLog(@"sid = %d, name = %@ pass = %@, score = %d",sid,name,password,score);
}
}
#pragma mark - 插入数据
-(void)testInsertData
{
int sid = 1024;
NSString *username = @"pangzi";
NSString *password = @"1315";
int score = 58;
//FMDB中?作为数据占位符, 和%d类似
NSString *sql = @"INSERT INTO studentInfo(sid,username,password,score) VALUES(?,?,?,?)";
//特别注意: ?处需要的时字符串, 其他数据转化为字符串传入
BOOL b = [_databse executeUpdate:sql,
[NSString stringWithFormat:@"%d",sid],
username,
password,
[NSString stringWithFormat:@"%d",score]];
NSLog(@"INSERT b = %d",b);
}
#pragma mark - 创建数据库中的表
-(void)testCreateTable
{
//创建表
//学生信息
// 学号sid, 姓名username, 密码password, 成绩score
NSString *sql = @"CREATE TABLE IF NOT EXISTS studentInfo(sid INTEGER,username varchar(32),password varchar(32),score INTEGER)";
//执行查询语句
//执行SELECT, 使用executeQuery
//_databse executeQuery:<#(NSString *), ...#>
//除了查询语句, 其他语句使用executeUpdate执行
BOOL b = [_databse executeUpdate:sql];
NSLog(@"Create table is %d",b);
}