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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,431评论 6 544
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,637评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,555评论 0 383
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 63,900评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,629评论 6 412
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 55,976评论 1 328
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 43,976评论 3 448
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,139评论 0 290
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,686评论 1 336
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,411评论 3 358
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,641评论 1 374
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,129评论 5 364
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,820评论 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,233评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,567评论 1 295
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,362评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,604评论 2 380

推荐阅读更多精彩内容