iOS数据库篇——FMDB简介

前言

如果不是为了深入了解FMDB,只求能用就行,只要记住下面这句话就行了:在FMDB中,除了查询以外的所有操作都称为'更新'(create、drop、insert、update、delete等)
啥也别说了,直接介绍FMDB。

FMDB介绍

1. 什么是FMDB?

FMDB是iOS开发平台的SQLite数据库框架
FMDB是以OC的封装封装了SQLite的C语言API

2. FMDB优点

使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码
与苹果自带的Core Data框架相比更加的轻量和灵活
提供了多线程安全的数据库操作方法,有效的防止数据混乱

3. GitHub

FMDB

4. 导入

导入什么的可以自己去GitHub上下载然后手动导入,也可以直接使用cocoaPod自动导入,详细的步骤请移步FMDB官方GitHub。

5. 编码之前

在编码之前,我们很有必要先把导入进来的FMDB库给大致浏览一下。

FMDB概览

从图中我们可以知道,FMDB由FMDatabaseFMDatabaseAdditionsFMDatabasePoolFMDatabaseQueueFMResultSet五个类组成。大概浏览的话 直接只看.h中的内容就可以了,至于实现就不用看了。

主要的核心类有三个:

  1. FMDatabase
    一个FMDatabase对象就代表一个单独的SQLite数据库,这个类主要是用来创建数据库、创建表、增删改查数据等功能的,简单概括来说就是执行SQL语句的。

  2. FMResultSet
    这个类的主要作用是用来保存执行查询SQL的结果。

  3. FMDatabaseQueue
    用于在多线程中执行多个查询或者更新,它是线程安全的

FMDB编码

有计算机基础的都知道,要想进行数据库操作,首先要有那么一个能够让你操作的数据库(系统级别的数据库一般是禁止修改的),有了可供修改的数据库之后,我们就可以建表插入数据了。(说句废话:数据的存储是建立在数据表的基础上,不是直接插入到数据库的)

从上面加粗的文字中我们就知道了操作数据库的步骤了:

1. 建立数据库

通过制定SQLite数据库文件路径来创建FMDatabase对象。我们这里就将数据库的位置定为沙盒中的tmp了(慎重,我这里只是为了演示,在特定情况下,这里的数据会被系统回收的),数据库名字定为tmp,后缀必须是db。

    // 创建数据库
    NSString *path = [NSTemporaryDirectory() stringByAppendingPathComponent:@"tmp.db"];
    self.db = [FMDatabase databaseWithPath:path];

2. 打开/关闭数据库

就像看书一样,有了可以看的书,接下来的动作就是看书咯;同理,有了我们自己的数据库,想要操作就必须先打开数据库建立连接。

    // 打开数据库
    if (![self.db open]) {
        self.db = nil;
        NSLog(@"数据库打开失败");
        return;
    }

在不使用数据库的时候我们就可以关闭数据库连接

[self.db close];

3. 操作数据库

在本篇文章开篇的时候我已经说了,在FMDB中,除了查询以外的所有操作都称为'更新'(create、drop、insert、update、delete等),所以在操作数据库这一步我们只需要分为更新和查询两种情况就可以了。

1. 更新

在FMDB中,除了查询以外的其他所有操作,都可以称之为“更新”

使用executeUpdate:方法执行更新:

- (BOOL)executeUpdate:(NSString*)sql, ...

- (BOOL)executeUpdateWithFormat:(NSString*)format, ...

- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
  • 创建表

创建表sql:create table 表名 (字段1, 字段2, 字段3, ...);

这里我们指定要创建的表的名字为t_student,表中包含有id(主键、自增、integer类型)、name(学生姓名)、age(学生年龄)这三个字段,创建表代码如下:

    NSString *sql = @"create table if not exists t_student (id integer primary key autoincrement, name text not null, age integer not null)";
    if ([self.db executeUpdate:sql]) {
        NSLog(@"创建表t_student成功");
    }else {
        NSLog(@"创建表t_student失败");
    }

或者

if ([self.db executeUpdate:@"create table if not exists t_students (id integer primary key autoincrement, name text not null, age integer not null);" withArgumentsInArray:@[]]) {
        NSLog(@"创建表成功");
    }else {
        NSLog(@"创建表失败");
    }

亦或者

if ([self.db executeUpdateWithFormat:@"create table if not exists t_students (id integer primary key autoincrement, name text not null, age integer not null);"]) {
        NSLog(@"创建表成功");
    }else {
        NSLog(@"创建表失败");
    }

这里主要是在sql语句中没有参数,所以三种方法的区别不明显,在下面的增删改中的示例你就可以看出来这几种的区别了。

  • 新增数据

新增数据sql:insert into 表名 (字段1, 字段2, ...) values (值1, 值2, ...);
这里的字段1和值1一定要一一对应

我们新增一条张三同学的信息。
姓名:张三 年龄:20

executeUpdate: 函数参数sql语句中不确定的参数使用?来占位。
executeUpdateWithFormat: 函数参数sql语句中不确定的参数使用%@%d等来占位。

    NSString *name = @"张三";
    int age = 20;
    // 这里的age参数,也可以写为这样的形式:@(age),但是绝对不能直接传int类型或者integer类型,那样运行会报错的。
    [self.db executeUpdate:@"insert into t_student (name, age) values (?, ?)", name, [NSNumber numberWithInt:age]];

或者

    NSString *name = @"张三";
    int age = 20;
    [self.db executeUpdateWithFormat:@"insert into t_student (name, age) values (%@, %@)", name, @(age)];

亦或者

NSString *name = @"张三";
    int age = 20;
    [self.db executeUpdate:@"insert into t_student (name, age) values (?, ?)" withArgumentsInArray:@[name, @(age)]];
插入成功
  • 修改数据

更改sql:update 表名 set 列名 = 新值 where 列名 = 某值

我们修改刚才插入的那条数据,将其年龄改为10岁

    NSString *name = @"张三";
    int ageNew = 10;
    // 这里是以参数的形式展示,也可以用注释中的那种方式
    // [self.db executeUpdate:@"update t_student set age = 10 where name = '张三'"];
    [self.db executeUpdate:@"update t_student set age = ? where name = ?", @(ageNew), name];

或者

    NSString *name = @"张三";
    int ageNew = 10;
    [self.db executeUpdateWithFormat:@"update t_student set age = %@ where name = %@", @(ageNew), name];

亦或者

    NSString *name = @"张三";
    int ageNew = 10;
    [self.db executeUpdate:@"update t_student set age = ? where name = ?" withArgumentsInArray:@[@(ageNew), name]];
更改信息成功
  • 删除数据

删除sql:delete from 表名 where 列名 = 某值

删除数据可以单独删除一条数据或者是把表中的数据全部都删除

删除一条数据

    // 删除t_student表中的某一条数据
    [self.db executeUpdate:@"delete from t_student where name = '张三'"];

删除t_student表中所有的数据

    // 删除t_student表中的所有数据
    [self.db executeUpdate:@"delete from t_student"];
  • 删除表

删除表sql:drop table 表名

删除t_student表

[self.db executeUpdate:@"drop table t_student"];
2. 查询

查询方法:

- (FMResultSet *)executeQuery:(NSString*)sql, ...

- (FMResultSet *)executeQueryWithFormat:(NSString*)format, ...

- (FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
  • 查询t_student表中的所有数据

查询sql:select 列名 from 表名的所有值
以及
select * from 表名

查询t_student表中的所有的学生名字

    // 查询t_student表中的学生名字
    // 执行查询语句
    FMResultSet *result = [self.db executeQuery:@"select name from t_student"];
    // 遍历查询结果
    while ([result next]) {
        NSLog(@"name: %@", [result stringForColumn:@"name"]);
    }

查询t_student表中的所有数据

    // 查询t_student表中的内容
    FMResultSet *result = [self.db executeQuery:@"select * from t_student"];
    while ([result next]) {
        NSLog(@"id: %d   name: %@   age: %d", [result intForColumnIndex:0], [result stringForColumn:@"name"], [result intForColumnIndex:2]);
    }

不熟悉或者不会数据库增删改查的同学以及想要学习更复杂的sql语句的可以移步W3School进行深入学习。

友情链接:W3School

推荐阅读更多精彩内容