1.FMDB简介

  • 什么是FMDB

FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API.

  • 为什么使用FMDB

使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码,对比苹果自带的Core Data框架,更加轻量级和灵活,它是对libsqlite3框架的封装,用起来的步骤与SQLite使用类似,提供了多线程安全的数据库操作方法,有效地防止数据混乱.所以是线程安全的.

2.FMDB优缺点

优点:
1.对多线程的并发操作进行处理,所以是线程安全的;
2.以OC的方式封装了SQLite的C语言API,使用起来更加的方便;
3.FMDB是轻量级的框架,使用灵活。

缺点:
1.因为它是OC的语言封装的,只能在iOS开发的时候使用,所以在实现跨平台操作的时候存在局限性。

FMDB中重要的类:

FMDatabase:一个FMDatabase对象就代表一个单独的SQLite数据库,用来执行SQL语句,对数据库进行增、删、改、查操作,是重要事件的执行者。
FMResultSet:使用FMDatabase执行查询后的结果集。
FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的。

3.FMDB的使用:

①.下载FMDB文件(gitHub链接:https://github.com/ccgus/fmdb),并将FMDB文件夹添加到项目中(也可使用CocoaPods导入,CocoaPods怎么导入第三方库我就不多说了,之前的博客已经详细描述过了).

②.导入libsqlite3.0框架,导入头文件FMDatabase.h.
③.代码实现,与SQLite使用步骤相似,创建数据库路径,获得数据库路径,打开数据库,然后对数据库进行增、删、改、查操作,最后关闭数据库。

  • 创建FMDatabase对象,参数为SQLite数据库文件路径.
  •  //第一步:创建sql语句(创建学生表)
    NSString *createSql = @"create table if not exists t_student(id integer primary key autoincrement not null, name text not null, age integer not null, sex text not null)"; //第二步:找到存储路径
    NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:];
    NSLog(@"%@", document);
    self.filePath = [document stringByAppendingPathComponent:@"student.sqlite"];
    NSLog(@"%@", self.filePath);
    //第三步:使用路径初始化FMDB对象(其实到这步,数据库的创建就算是完成了)
    self.dataBase = [FMDatabase databaseWithPath:self.filePath];
    //第四步:数据库执行相关操作
    //需要判断数据库打开的时候才进行执行语句,才开始创建表.
    if ([self.dataBase open]) { BOOL result = [self.dataBase executeUpdate:createSql];
    if (result) {
    NSLog(@"建表成功");
    } else {
    NSLog(@"建表失败");
    }
    }
    //上面的步骤是在数据库中创建了学生表
    //第五步:关闭数据库(为了节约资源,随即使用完了就关闭)
    [self.dataBase close];

    创建完学生表之后,就可以进行下一步的操作了,增删改查:

  • 每次对数据库进行操作的时候,我们都要重新打开数据库,操作完了,记得关闭数据库,这样可以更加节省资源.
  • 一切不是SELECT命令的命令都视为更新。这包括 CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。
         简单来说,只要不是以SELECT(查询)开头的命令都是更新命令,更新操作统一使用语句executeUpdate:
  • 执行更新返回一个BOOL值。YES表示 执行成功,否则表示有错误。你可以调用 -lastErrorMessage 和 -lastErrorCode方法来得到更多信息。
  • 这里简单说一下executeUpdate的几个需要注意的地方:

//1.executeUpdate:  不确定的参数用?来占位(后面参数必须是oc对象)推荐使用该语句
   [self.dataBase executeUpdate:@"INSERT INTO t_student (name, age) VALUES (?,?)",name,@(age)];
//2.executeUpdateWithFormat:不确定的参数用%@,%d等来占位 (参数为原始数据类型,执行语句不区分大小写)
   [self.dataBase executeUpdateWithFormat:@"insert into t_student (name,age) values (%@,%i)", name,age];

//3.数组   执行语句不区分大小写
   [self.db executeUpdate:@"INSERT INTO t_student(name,age) VALUES  (?,?)"  withArgumentsInArray:@[name, @(age)]];

代码示例:

 #pragma mark - 添加
- (IBAction)insertAction:(id)sender {
//第一步:打开数据库
[self.dataBase open];
//第二步:spl语句
NSArray *nameArray = [NSArray arrayWithObjects:@"MBBoy", @"炸天", @"小明", nil];
for (int i = ; i < nameArray.count; i++) {
NSString *name = [nameArray objectAtIndex:i];
//插入语句
//NSString *insertSql = @"insert into t_student(name, age, sex) values (?,?,?)";
//executeUpdate返回的第一个参数是insertSql语句,逗号后面的是需要符的值.
BOOL result = [self.dataBase executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", name, @, @"男"];
if (result) {
NSLog(@"插入成功");
} else {
NSLog(@"插入失败%d", result);
}
}
//用完就关闭
[self.dataBase close];
}

删除和修改也是一样的,只要不是查询(SELECT),都是可以用更新executeUpdate来处理数据:

 #pragma mark - 修改
- (IBAction)updateAction:(id)sender {
//第一步:打开数据库
[self.dataBase open];
BOOL result = [self.dataBase executeUpdate:@"update t_student set name = ? where name = ?", @"孟玲旭", @"MBBoy"];
if (result) {
NSLog(@"更改成功");
} else {
NSLog(@"更改失败%d", result);
} [self.dataBase close];
} #pragma mark - 删除
- (IBAction)deleteAction:(id)sender {
[self.dataBase open];
//执行sql语句
BOOL result = [self.dataBase executeUpdate:@"delete from t_student where name = ?", @"孟玲旭"];
if (result) {
NSLog(@"删除成功");
} else {
NSLog(@"删除失败%d", result);
}
[self.dataBase close];
}

这里我们来看看查找与之前的增,删,改有哪些不同的地方:

1.  SELECT命令就是查询,执行查询的方法是以-excuteQuery开头的。
2.  执行查询时,如果成功返回FMResultSet对象,错误返回nil。与执行更新相同,支持使用NSError参数。
3.  同时,你也可以使用-lastErrorCode和-lastErrorMessage获知错误信息。

 #pragma mark - 查找
- (IBAction)searchAction:(id)sender {
//查询表中的所有数据
[self.dataBase open];
//查询结果引入的类FMResultSet,而之前的增删改返回的类型是BOOL值类型.
//使用的方法也不一样,这里我们使用的是查询Query,查询整个表格数据.
FMResultSet *resuletSet = [self.dataBase executeQuery:@"select * from t_student"];
//此处额外补充一下:根据条件查找
//根据条件查询(id<14的元素)
 FMResultSet *resultSet = [self.dataBase executeQuery:@"select * from t_student where id<?", @(14)];
//遍历出需要的结果内容(内部自带的next方法逐步循环set,打印结果)
while ([resuletSet next]) {
NSString *name = [resuletSet objectForColumnName:@"name"];
NSInteger age = [resuletSet intForColumn:@"age"];
NSString *sex = [resuletSet objectForColumnName:@"sex"];
NSLog(@"name = %@, age = %ld, sex = %@", name, age, sex);
}
[self.dataBase close]; }

FMResultSet提供了很多方法,来获取对应字段的信息:(红色为常用查找类)
    intForColumn:
    longForColumn:
    longLongIntForColumn:
    boolForColumn:
    doubleForColumn:
    stringForColumn:
    dataForColumn:
    dataNoCopyForColumn:
    UTF8StringForColumnIndex:
    objectForColumnName:

还有一些,我没有列举出来,大家可以自己试试,上面的这些就已经大大满足了我们需要查找的类型需求.

如果我们想要销毁该student表格,可以执行下面语句:

//如果表格存在 则销毁,同样使用的是更新,只要不是select,都可以用更新操作来处理数据.
[self.dataBase executeUpadate:@"drop table if exists t_student"];

4.FMDB在多线程中的使用:

FMDatabase实例能否在多线程中使用?

如果应用中使用了多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 应用中不可在多个线程中共同使用一个FMDatabase对象操作数据库,这样会引起数据库数据混乱(例如使用两个线程同时对数据库进行更新和查找)。 为了多线程操作数据库安全,FMDB使用了FMDatabaseQueue。
多个线程更新相同的资源导致数据竞争时使用等待队列(等待现在执行的处理结束),也就是说我们使用FMDB实际上是在多线程中的串行队列中使用,并不支持并行队列。

示例代码:

 #pragma mark - 以队列的形式添加数据,是FMDB比较常用的形式
- (IBAction)insertStudentByLineAtion:(id)sender {
//以队列的形式添加数据是FMDB比较常用的添加方式
[self.dataBase open];
//FMDB不支持多个线程同时操作,所以一般以串行的方式实现相关操作
//第一步:创建操作队列
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:self.filePath];
//标识:记录是否操作成功
__block BOOL isSucceed = YES; //第一个队列语句的isSucceed根据
//第二步:把所需要的事件打包放在操作队列中
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
//串行队列 && isSucceed 是依据上一条语句是否成功插入,否则不执行本条语句.一个执行完,下一个才执行.
isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"隔壁老王", @"", @"男"] && isSucceed;
isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"赵符壹", @"", @"未知"] && isSucceed;
isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"AJAR", @"", @"男"] && isSucceed;
//如果有错误,就会将它返回
if (!isSucceed) {
//block返回的参数rollback进行处理(bool类型的指针)
//有错误,直接返回,不再继续往下执行
*rollback = YES;
return ;
}
}];
[self.dataBase close];
}

第三方库FMDB的使用的更多相关文章

  1. Objective-C ,ios,iphone开发基础:使用第三方库FMDB连接sqlite3 数据库,实现简单的登录

    第一步:下载第三方库,点击 连接 下载, 第二部:准备数据库:按照连接&中博客的步骤实现数据库, 数据库的设计大致如下表: id        username             pas ...

  2. IOS数据持久化存储之SQLite3第三方库FMDB的使用

    SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非常好的选择,无论是Android还是IOS,都内置了SQLite数据库,现在的版本都是SQLite3.在IOS中使用SQLite如果使 ...

  3. ios数据存储——数据库:SQlite3以及第三方库FMDB

    [reference]http://blog.csdn.net/mad1989/article/details/9322307 原生数据库:SQlite3 一.必备条件 在ios项目中使用sqlite ...

  4. IOS学习笔记28—SQLite3第三方库之FMDB

    本文转载至 http://blog.csdn.net/happyrabbit456/article/details/11609451 SQLite是一种小型的轻量级的关系型数据库,在移动设备上使用是非 ...

  5. QF——iOS中的数据库操作:SQLite数据库,第三方封装库FMDB,CoreData

    SQLite数据库: SQLite是轻量级的数据库,适合应用在移动设备和小型设备上,它的优点是轻量,可移植性强.但它的缺点是它的API是用C写的,不是面向对象的.整体来说,操作起来比较麻烦.所以,一般 ...

  6. iOS-数据持久化-第三方框架FMDB的使用

    FMDB简单介绍 一.简单说明 1.什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 2.FMDB的优点 使用起来更加面向对象,省去了 ...

  7. 常用iOS第三方库以及XCode插件介绍

    第三方库 CocoaPod CocoaPod并不是iOS上的第三方库 而是大名鼎鼎的第三方库的管理工具 在CocoaPod没有出现之前 第三方库的管理是非常痛苦的 尤其是一些大型的库(比如nimbus ...

  8. iOS,第三方库使用

    1.ASIHttpRequest网络请求库 2.MBProgressHUD指示层库 3.Toast+UIView提示库 4.SDWebImage图片缓存库 5.MGSwipeTableCell单元格侧 ...

  9. 个人常用iOS第三方库以及XCode插件介绍

    第三方库 CocoaPod CocoaPod并不是iOS上的第三方库 而是大名鼎鼎的第三方库的管理工具 在CocoaPod没有出现之前 第三方库的管理是非常痛苦的 尤其是一些大型的库(比如nimbus ...

随机推荐

  1. 使用Python脚本操作MongoDB的教程

    Reference:  http://www.jb51.net/article/64225.htm

  2. 隐马尔可夫模型(HMM)原理

    本文主要讨论隐马尔科夫模型的三大要素,三大假设和三大问题. 1.引入 隐马尔可夫模型是一个关于时序的概率模型,它描述了一个由隐藏的马尔可夫链生成状态序列,再由状态序列生成观测序列的过程.其中,状态之间 ...

  3. 关键词匹配(Ac自动机模板题)

    2772: 关键词匹配 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 10  Solved: 4[Submit][Status][Web Board] ...

  4. Python模块学习:threading 多线程控制和处理

    Reference:http://python.jobbole.com/81546/ threading.Thread Thread 是threading模块中最重要的类之一,可以使用它来创建线程.有 ...

  5. PHP 中 static 和 self 的区别

    使用 self:: 或者 __CLASS__ 对当前类的静态引用,取决于定义当前方法所在的类: 使用 static:: 不再被解析为定义当前方法所在的类,而是在实际运行时计算的.也可以称之为" ...

  6. docker tag

    docker tag 命令以及其中的一些概念--之我见 1.  重要的本质的东西是 image - docker 最有用的东西是image,这个应该可以被大部分人接受 - 查看官网的 tag 命令,一 ...

  7. C++ STL算法系列1---unique , unique_copy函数

     一.unique函数 类属性算法unique的作用是从输入序列中“删除”所有相邻的重复元素. 该算法删除相邻的重复元素,然后重新排列输入范围内的元素,并且返回一个迭代器(容器的长度没变,只是元素顺序 ...

  8. CSS的position设置

    CSS的position设置: <%@ page language="java" contentType="text/html; charset=UTF-8&quo ...

  9. windows下安装php5.2.*,php5.3.*,php5.4.*版本的memcache扩展

    注:如使用集成环境成功率低,请自行配置php apache,表示win7下wamp php5.4.3基础上配置拓展,成功率极低.费时. 拓展安装调试方法: 编写调试php文件 <?php  me ...

  10. 关于WIN10开机无法输入密码的问题

    昨日,电脑 遇到了开机无法输入密码的问题,神烦. 作为一个计算狗,怎么能直接装系统(百度了一堆方法,装系统,果真万能)呢. 所以,深刻的分析了下. 1 .首先说明基本情况. 计算机品牌:ASUS 系统 ...