转自:http://blog.devtang.com/blog/2012/04/22/use-fmdb/

前言

SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。但是,原生的SQLite API在使用上相当不友好,在使用时,非常不便。于是,开源社区中就出现了一系列将SQLite API进行封装的库,而FMDB (https://github.com/ccgus/fmdb) 则是开源社区中的优秀者。

FMDB在使用上相当方便。以下是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
NSString* docsdir = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString* dbpath = [docsdir stringByAppendingPathComponent:@"user.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:dbpath];
[db open];
FMResultSet *rs = [db executeQuery:@"select * from people"];
while ([rs next]) {
NSLog(@"%@ %@",
[rs stringForColumn:@"firstname"],
[rs stringForColumn:@"lastname"]);
}
[db close];

可以看到,使用FMDB后的数据库代码清晰明了,比原生的API优雅多了。另外,FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。

使用说明

该使用说明主要翻译自fmdb的github项目说明文档: https://github.com/ccgus/fmdb

引入相关文件

首先将FMDB从github上clone下来,然后将以下文件copy到你的工程中:

1
2
3
4
5
6
7
8
9
10
FMDatabase.h
FMDatabase.m
FMDatabaseAdditions.h
FMDatabaseAdditions.m
FMDatabasePool.h
FMDatabasePool.m
FMDatabaseQueue.h
FMDatabaseQueue.m
FMResultSet.h
FMResultSet.m

建立数据库

建立数据库只需要如下一行即可,当该文件不存在时,fmdb会自己创建一个。如果你传入的参数是空串:@”” ,则fmdb会在临时文件目录下创建这个数据库,如果你传入的参数是 NULL,则它会建立一个在内存中的数据库。

1
FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];

打开数据库

使用如下语句,如果打开失败,可能是权限不足或者资源不足。通常打开完操作操作后,需要调用close方法来关闭数据库。

1
2
3
4
5
6
7
8
if (![db open]) {
// error
return;
}
// some operation
// ... [db close];

执行更新操作

除了Select操作之外,其它的都是更新操作。更新操作使用如下方法,如果有错误,可以用error参数中获得。

1
-[FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:]

执行查询操作

查询操作示例如下。注意:即使操作结果只有一行,也需要先调用FMResultSet的next方法。

1
2
3
4
5
6
7
8
9
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
//retrieve values for each record
} FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
int totalCount = [s intForColumnIndex:0];
}

FMDB提供如下多个方法来获取不同类型的数据:

1
2
3
4
5
6
7
8
9
10
11
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:

通常情况下,你并不需要关闭FMResultSet,因为相关的数据库关闭时,FMResultSet也会被自动关闭。

数据参数

通常情况下,你可以按照标准的SQL语句,用?表示执行语句的参数,如:

1
INSERT INTO myTable VALUES (?, ?, ?)

然后,可以我们可以调用executeUpdate方法来将?所指代的具体参数传入,通常是用变长参数来传递进去的,如下:

1
2
NSString *sql = @"insert into User (name, password) values (?, ?)";
[db executeUpdate:sql, user.name, user.password];

这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要封装成对应的包装类才行,如下所示:

1
2
3
4
// 错误,42不能作为参数
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];
// 正确,将42封装成 NSNumber 类
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

线程安全

如果我们的app需要多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。切记不能在多个线程中共同一个FMDatabase对象并且在多个线程中同时使用,这个类本身不是线程安全的,这样使用会造成数据混乱等问题。

使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。在闭包中操作数据库,而不直接参与FMDatabase的管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 创建,最好放在一个单例的类中
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath]; // 使用
[queue inDatabase:^(FMDatabase *db) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; FMResultSet *rs = [db executeQuery:@"select * from foo"];
while ([rs next]) {
// …
}
}]; // 如果要支持事务
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]]; if (whoopsSomethingWrongHappened) {
*rollback = YES;
return;
}
// etc…
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

工具

为了查看Sqlite中的数据,一个好的图形化界面的数据库管理程序是必不可少的。mysql有phpMyAdmin,那么sqlite呢?

我主要使用的是Firefox的一个名为SQLite Manager的插件,安装此插件后,可以直接打开后缀名为sqlite的数据库文件。SQLite Manager提供一个图形化的界面来执行数据查询或更改操作。如下图所示:

总结

FMDB将SQLite API进行了很友好的封装,使用上非常方便,对于那些使用纯Sqlite API来进行数据库操作的app,可以考虑将其迁移到基于FMDB上,这对于以后数据库相关功能的开发维护,可以提高不少效率。

FMDB的使用方法的更多相关文章

  1. FMDB的使用方法(附Demo)

    http://www.jianshu.com/p/54e74ce87404 最近在项目中需要在多个页面对同样的数据进行相关操作,于是便用到了FMDB数据库操作,以下便是FMDB的一些简单的使用方法.附 ...

  2. FMDB简单封装和使用

    工具:火狐浏览器+SQLite Manager插件 ; Xcode; FMDB库; 效果: 项目地址: https://github.com/sven713/PackFMDB 主要参考这两篇博客: 1 ...

  3. FMDB浅析

    一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向对象的思想,让我们不必使用繁琐的C语言API函数,比起直接操作SQLite更加方便. FMDB优 ...

  4. Swift使用单个案件管理FMDB数据库

    下班... 抢 我曾经Swift使用单一个案管理FMDB数据库的方法共享出来: // Created by 秦志伟 on 14-6-12. import UIKit class ZWDBManager ...

  5. FMDB浅析(思想)

    http://www.cnblogs.com/OTgiraffe/p/5931800.html 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQLite的API进行了封装,加上了面向 ...

  6. iOS学习笔记17-FMDB

    上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...

  7. iOS学习笔记17-FMDB你好!

    上一节我已经介绍了SQLite的简单使用,不了解的可以提前去看一下iOS学习笔记16-数据库SQLite,这节我们来讲下FMDB. 一.FMDB介绍 FMDB是一种第三方的开源库,FMDB就是对SQL ...

  8. javaSE27天复习总结

    JAVA学习总结    2 第一天    2 1:计算机概述(了解)    2 (1)计算机    2 (2)计算机硬件    2 (3)计算机软件    2 (4)软件开发(理解)    2 (5) ...

  9. FMDB 使用方法

    优秀的第三方库,README 也是很优秀的,理解了 README,会对使用带来很多便利. ARC 和 MRC 项目中使用 ARC 还是 MRC,对使用 FMDB 都没有任何影响,FMDB 会在编译项目 ...

随机推荐

  1. 在CentOS 7上安装.NET Core R2跑Hello World

    前言 在上个月.NET Core出了最新版本预览版,只是在Window系统上试验了一下.原本想等发布正式版的时候在linux系统上试试,可能还需要一段时间,刚好有空可以折腾一下. 由于之前安装的Ubu ...

  2. PHP基础知识第一趴

    今天来贴一贴我的一张部分php基础知识的思维导图.未完,待续......慢慢'补枪'(为了让引号内的期望输出内容<strong>变成</strong>现实,应该使用双引号?那就 ...

  3. 利用scp传输文件

    在linux下一般用scp这个命令来通过ssh传输文件. 从服务器上下载文件 scp username@servername:/path/filename /var/www/local_dir(本地目 ...

  4. Warning: mysql_connect(): No such file or directory 解决方案总结(操作系统: Mac)

    说明: 本文主要内容参考: Mac下PHP连接MySQL报错"No such file or directory"的解决办法, 并进行个人补充 1. 运行环境: Mac OS X 10.11.4 (M ...

  5. 来玩Play框架02 响应

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 我上一章总结了Play框架的基本使用.这一章里,我将修改和增加响应. HTTP协议 ...

  6. java web学习总结(三十) -------------------JSTL表达式

    一.JSTL标签库介绍 JSTL标签库的使用是为弥补html标签的不足,规范自定义标签的使用而诞生的.使用JSLT标签的目的就是不希望在jsp页面中出现java逻辑代码 二.JSTL标签库的分类 核心 ...

  7. 关于mysql 和Oracle的一大堆麻烦问题的解决方案

    [INS-20802] Oracle Net Configuration Assistant 失败 在百度上找了半天并没有找到可靠的解决方案,最后是可以安装完成的,之后我 通过SQL Plus连接就报 ...

  8. js 隐式转换

    1.数字number与字符串string相加的就,最后会得到一个字符串string:'1'+3='13' 2.数字number与字符串string相减,最后会得到一个数字number:'1'-0=1, ...

  9. 5.1 JS中Object类型

    1.Object类型是引用类型中的一种. 2.创建Object实例(对象)的方式: 方式1:使用new操作符,后面跟上Object构造函数.如: var obj = new Object();//创建 ...

  10. 阶段一:AsyncTask的三个属性值和四个步骤

    “阶段一”是指我第一次系统地学习Android开发.这主要是对我的学习过程作个记录. 最近学到用AsyncTask来处理有关网络的操作.虽然代码看上去不是很复杂,但仍有很多地方有疑惑.所以研读了一下A ...