FMDB封装了SQLite的C语言API,更加面向对象。
首先需要明确的是FMDB中的三个类。

  • FMDatabase:可以理解成一个数据库。
  • FMResultSet:查询的结果集合。
  • FMDatabaseQueue:运用多线程,可执行多个查询、更新。线程安全。

FMDB基本语法

查询

  1. [db executeQuery:@"select id, name, age from t_person"]

更新

  1. // CREATE, UPDATE, INSERT, DELETE, DROP,都使用executeUpdte
  2. [db executeUpdate:@"create table if not exists t_person (id integer primary key autoincrement, name text, age integer)"]

FMDB的基本使用

在项目中导入FMDB框架和sqlite3.0.tbd,导入头文件。

1. 打开数据库,并创建表

  1. #import "ViewController.h"
  2. #import <FMDB.h>
  3. @interface ViewController ()
  4. @end
  5. @implementation ViewController{
  6. FMDatabase *db;
  7. }
  8. - (void)openCreateDB {
  9. //存放数据的路径
  10. NSString *path = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject;
  11. NSString *filePath = [path stringByAppendingPathComponent:@"person.sqlite"];
  12. //初始化FMDatabase
  13. db = [FMDatabase databaseWithPath:filePath];
  14. //打开数据库并创建person表,person中有主键id,姓名name,年龄age
  15. if ([db open]) {
  16. BOOL success = [db executeUpdate:@"create table if not exists t_person (id integer primary key autoincrement, name text, age integer)"];
  17. if (success) {
  18. NSLog(@"创表成功");
  19. }else {
  20. NSLog(@"创建表失败");
  21. }
  22. } else {
  23. NSLog(@"打开失败");
  24. }
  25. }

2. 插入数据

  1. -(void)insertData {
  2. BOOL success = [db executeUpdate:@"insert into t_person(name,age) values(?,?)",@"jack",@17];
  3. if (success) {
  4. NSLog(@"添加数据成功");
  5. } else {
  6. NSLog(@"添加数据失败");
  7. }
  8. }

3. 删除数据

  1. -(void)deleteData {
  2. BOOL success = [db executeUpdate:@"delete from t_person where name = 'lily'"];
  3. if (success) {
  4. NSLog(@"删除数据成功");
  5. } else {
  6. NSLog(@"删除数据失败");
  7. }
  8. }

4. 修改数据

  1. -(void)updateData {
  2. BOOL success = [db executeUpdate:@"update t_person set name = 'lily' where age = 17"];
  3. if (success) {
  4. NSLog(@"更新数据成功");
  5. } else {
  6. NSLog(@"更新数据失败");
  7. }
  8. }

5. 查询数据

  1. //用FMResultSet接收查询结果
  2. FMResultSet *set = [db executeQuery:@"select id, name, age from t_person"];
  3. //遍历查询结
  4. while ([set next]) {
  5. int ID = [set intForColumnIndex:0];
  6. NSString *name = [set stringForColumnIndex:1];
  7. //也可以这样拿到每条数据的姓名
  8. //NSString *name = [result stringForColumn:@"name"];
  9. int age = [set intForColumnIndex:2];
  10. NSLog(@"%d,%@,%d",ID,name,age);
  11. }

6. 删除表

  1. -(void)dropTable {
  2. BOOL success = [db executeUpdate:@"drop table if exists t_person"];
  3. if (success) {
  4. NSLog(@"删除表成功");
  5. } else {
  6. NSLog(@"删除表失败");
  7. }
  8. }

FMDatabaseQueue基本使用

FMDatabase是线程不安全的,当FMDB数据存储想要使用多线程的时候,FMDatabaseQueue就派上用场了。

  • 初始化FMDatabaseQueue的方法与FMDatabase类似
  1. //数据文件路径
  2. NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  3. NSString *filePath = [path stringByAppendingPathComponent:@"student.sqlite"];
  4. //初始化FMDatabaseQueue
  5. FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:filePath];
  • 在FMDatabaseQueue中执行命令的时候也是非常方便,直接在一个block中进行操作
  1. -(void)FMDdatabaseQueueFunction {
  2. NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  3. //数据文件路径
  4. NSString *filePath = [path stringByAppendingPathComponent:@"student.sqlite"];
  5. //初始化FMDatabaseQueue
  6. FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:filePath];
  7. //在block中执行SQLite语句命令
  8. [dbQueue inDatabase:^(FMDatabase * _Nonnull db) {
  9. //创建表
  10. [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer)"];
  11. //添加数据
  12. [db executeUpdate:@"insert into t_student(name,age) values(?,?)",@"jack",@17];
  13. [db executeUpdate:@"insert into t_student(name,age) values(?,?)",@"lily",@16];
  14. //查询数据
  15. FMResultSet *set = [db executeQuery:@"select id, name, age from t_student"];
  16. //遍历查询到的数据
  17. while ([set next]) {
  18. int ID = [set intForColumn:@"id"];
  19. NSString *name = [set stringForColumn:@"name"];
  20. int age = [set intForColumn:@"age"];
  21. NSLog(@"%d,%@,%d",ID,name,age);
  22. }
  23. }];
  24. }

FMDB中的事务

  • 事务(Transaction)是不可分割的一个整体操作,要么都执行,要么都不执行。
  • FMDB中有事务的回滚操作,也就是说,当一个整体事务在执行的时候出了一点小问题,则执行回滚,之后这套事务中的所有操作将整体无效。
  1. //数据库路径
  2. NSString *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject;
  3. NSString *filePath = [path stringByAppendingPathComponent:@"student.sqlite"];
  4. //初始化FMDatabaseQueue
  5. FMDatabaseQueue *dbQueue = [FMDatabaseQueue databaseQueueWithPath:filePath];
  6. //FMDatabaseQueue的事务inTransaction
  7. [dbQueue inTransaction:^(FMDatabase * _Nonnull db, BOOL * _Nonnull rollback) {
  8. //创建表
  9. [db executeUpdate:@"create table if not exists t_student (id integer primary key autoincrement, name text, age integer)"];
  10. //循环添加2000条数据
  11. for (int i = 0; i < 2000; i++) {
  12. BOOL success = [db executeUpdate:@"insert into t_student(name,age) values(?,?)",@"jack",@(i)];
  13. //如果添加数据出现问题,则回滚
  14. if (!success) {
  15. //数据回滚
  16. *rollback = YES;
  17. return;
  18. }
  19. }
  20. }];