iOS学习47之第三方-FMDB

将 CocoaPods 安装后,按照 CocoaPods 的使用说明就可以将 FMDB 第三方集成到工程中,具体请看博客iOS学习46之第三方CocoaPods的安装和使用(通用方法)

1. FMDB简介

 1> 概述

  • iOS 中原生的 SQLite API 在进行数据存储的时候,需要使用 C语言 中的函数,操作比较繁琐。于是,就出现了一系列将SQLite API 进行封装的库,例如 FMDB、PlausibleDatabase、SQLitePersistentObjects 等。
  • FMDB 是一款简洁、易用的封装库。因此,在这里推荐使用第三方框架 FMDB,它是对 libsqlite3 框架的封装,用起来的步骤与 SQLite 使用类似,并且它对于多线程的并发操作进行了处理,所以是线程安全的。

 2> FMDB优缺点

  • 优点:

  对多线程的并发操作进行处理,所以是线程安全的;

  以OC的方式封装了SQLite的C语言API,使用起来更加的方便;

  FMDB是轻量级的框架,使用灵活。

  • 缺点:

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

 3> FMDB中重要的类

  • FMDatabase:一个 FMDatabase 对象就代表一个单独的 SQLite数据库,用来执行 SQL语句。
  • FMResultSet:使用 FMDatabase 执行查询后的结果集。
  • FMDatabaseQueue:用于在多线程中执行多个查询或更新,它是线程安全的。

 4> FMDB使用步骤

  • 第一步:使用 CocoaPods 将第三方集成到工程项目中
  • 第二步:导入 libsqlite3.0 框架,导入头文件 FMDatabase.h
  • 第三步:代码实现,与 SQLite 使用步骤相似,创建数据库路径,获得数据库路径,打开数据库,然后对数据库进行增、删、改、查操作,最后关闭数据库。

2. FMDB创建数据库和数据表

  • 第一步:获得数据库文件的路径

  创建FMDatabase对象时参数为SQLite数据库文件路径,该路径可以是以下三种方式之一:

   ① 文件路径。该文件路径无需真实存在,如果不存在会自动创建;

   ② 空字符串(@"")。表示会在临时目录创建一个空的数据库,当 FMDatabase 连接关闭时,文件也会被删除;

   ③ NULL。将创建一个内在数据库,同样的,当 FMDatabase 连接关闭时,数据将会被销毁。

  我们一般采用第一种方式来获得数据库文件的路径,具体实例代码如下:

   NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    self.filePath = [documentPath stringByAppendingPathComponent:@"student.sqlite"];

    NSLog(@"filePath = %@", self.filePath);
  • 第二步:使用路径初始化FMDB对象

  使用的初始化方法:

   + (instancetype)databaseWithPath:(NSString*)aPath

  实例代码:

    // 第四步:使用路径初始化FMDB对象
    self.database = [FMDatabase databaseWithPath:self.filePath];
  • 第三步:在和数据库交互之前,数据库必须是打开的。

  如果权限不足或者资源不足,则无法打开和创建数据库。

   // 需要判断数据库打开的时候才进行执行语句
   if (self.database.open) {
        // 创建表
    }
  • 第四步:创建表

  使用的执行SQL语句的方法:

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

  该方法的返回值是一个BOOL值,我们可以根据返回值,来判断SQL语句是否执行成功。

  实例代码:

    if (self.database.open) {
        // 建表语句
        NSString *createSql = @"create table if not exists t_student(id integer primary key autoincrement not null, name text not null, age integer not null, sax text not null)";
        // 执行建表语句,创建数据表
        BOOL result = [self.database executeUpdate:createSql];
        // 判断是否建表成功
        if (result) {
            NSLog(@"创表成功");
        } else {
            NSLog(@"创表失败");
        }
    }
  • 第五步:关闭数据库

  实例代码:

    // 第五步:关闭数据库
    [self.database close];

3. FMDB实现增、删、改、查

 1> FMDB—执行更新

  一切不是SELECT命令的命令都视为更新。这包括CREAT,UPDATE,INSERT,ALTER,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。

  简单来说,只要不是以 SELECT 开头的命令都是更新命令。

执行更新返回一个BOOL值。YES表示执行成功,否则表示有错误。你可以调用 -lastErrorMessage 和 -lastErrorCode方法来得到更多信息。

 2> 执行更新命令的相关方法

  • executeUpdate:  不确定的参数用 ? 来占位(后面参数必须是 OC 对象,;代表语句结束,也可以不写)

  增、删、改的代码实例:

// 增加(插入)数据
BOOL result = [self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?)", @"xiaoming", @12, @"男"];

// 更新数据
BOOL result = [self.database executeUpdate:@"update t_student set name = ? where name = ?", @"xiaoming", @"小明"];

// 删除数据
BOOL result = [self.database executeUpdate:@"delete from t_student where name = ?", @"xiaoming"]; 
  • executeUpdateWithFormat:不确定的参数用%@,%d等来占位 (参数为原始数据类型,执行语句不区分大小写)

  增、删、改的代码实例:

// 增加(插入)数据
BOOL result = [self.database executeUpdateWithFormat:@"insert into t_student (name, age, sax) values (%@, %i, %@);", @"xiaoming", @69, @"男"];

// 更新数据
BOOL result = [self.database executeUpdateWithFormat:@"update t_student set name = %@ where name = %@", @"xiaoming", @"小明"];

// 删除数据
BOOL result = [self.database executeUpdateWithFormat:@"delete from t_student where name = %@", @"xiaoming"];
  • executeUpdate:withArgumentsInArray:数组,直接使用数组

  增、删、改的代码实例:

// 增加(插入)数据
[self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?);"  withArgumentsInArray:@[@"xiaoming", @12, @"男"]];

// 更新数据
[self.database executeUpdate:@"update t_student set name = ? where name = ?;"  withArgumentsInArray:@[@"xiaoming", @"小明"]];

// 删除数据
[self.database executeUpdate:@"delete from t_student where name = ?;"  withArgumentsInArray:@[@"xiaoming"]];

  以上的方法大家可以根据自己的习惯和需求选择一种即可。

 3> FMDB—查询数据

  ① 概述  

  SELECT 命令就是查询,执行查询的方法是以 -excuteQuery 开头的。

  执行查询时,如果成功返回 FMResultSet 对象,错误返回 nil 。与执行更新相同,支持使用 NSError 参数。

  同时,你也可以使用 -lastErrorCode 和 -lastErrorMessage 获知错误信息。

  ② FMResultSet

  FMResultSet 提供了很多方法,来获取对应字段的信息:

    intForColumn:、longForColumn:、longLongIntForColumn:、boolForColumn:、doubleForColumn:、stringForColumn:、dataForColumn:、dataNoCopyForColumn:、UTF8StringForColumnIndex:、objectForColumn:

  ③ 执行查询语句

  查询整个表

    // 查询结果使用的类FMResultSet
    FMResultSet *resultSet = [self.database executeQuery:@"select * from t_student"];

  根据条件查询

    //根据条件查询
    FMResultSet *resultSet = [self.db executeQuery:@"select * from t_student where id<?;", @14];

  ④ 遍历结果集合

    while (resultSet.next) {
        NSInteger ID = [resultSet intForColumn:@"id"];
        NSString *name = [resultSet objectForColumnName:@"name"];
        NSInteger age = [resultSet intForColumn:@"age"];
        NSString *sax = [resultSet objectForColumnName:@"sax"];

        NSLog(@"id = %ld name = %@, age = %ld, sax = %@", ID, name, age, sax);
    }

 4> 完整实例代码

#import "ViewController.h"

// 第一步:引入框架,引入支持的类库(libsqlite3.0.tbd)
#import <FMDB.h>

@interface ViewController ()

/// 声明数据库对象
@property (nonatomic, strong) FMDatabase *database;

/// 声明存储路径
@property (nonatomic, strong) NSString *filePath;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    [self createTabe];
}

#pragma mark - 创建表
- (void)createTabe
{
    // 第一步:创建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, sax text not null)";

    // 第二步:找到存储路径
    NSString *documentPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
//    NSLog(@"document = %@", documentPath);
    self.filePath = [documentPath stringByAppendingPathComponent:@"student.sqlite"];
    NSLog(@"filePath = %@", 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];
}

#pragma mark - 插入
- (IBAction)insertIntoAction:(id)sender
{
    // 第一步:打开数据库
    [self.database open];

    // 第二步:进行相关的操作
    NSArray *nameArray = @[@"MBBoy", @"BoomSky", @"小明"];

    for (NSString *name in nameArray) {

        BOOL result = [self.database executeUpdate:@"insert into t_student(name, age, sax) values(?, ?, ?)", name, @69, @"男"]; // integer的数据不能在这里使用,必须使用一个对象型数据,比如NSNumber、NSString...

        [self.database executeUpdate:@"INSERT INTO t_student(name, age, sax) VALUES  (?, ?, ?);"  withArgumentsInArray:@[@"xiaoming", @12, @"男"]];

        if (result) {
            NSLog(@"插入成功");
        } else {
            NSLog(@"插入失败");
        }
    }
    [self.database close];// 更新数据// 删除数据// 增加(插入)数据
}

#pragma mark - 更新
- (IBAction)updateAction:(id)sender
{
    [self.database open];

    BOOL result = [self.database executeUpdate:@"update t_student set name = ? where name = ?", @"xiaoming", @"小明"];

    if (result) {
        NSLog(@"更新成功");
    } else {
        NSLog(@"更新失败");
    }

    [self.database close];
}

#pragma mark - 删除
- (IBAction)deleteAction:(id)sender
{
    [self.database open];
    BOOL result = [self.database executeUpdate:@"delete from t_student where name = ?", @"MBBoy"];
    if (result) {
        NSLog(@"删除成功");
    } else {
        NSLog(@"删除失败");
    }
    [self.database close];
}

#pragma mark - 查询
- (IBAction)selectAction:(id)sender
{
    [self.database open];

    // 查询结果使用的类FMResultSet
    FMResultSet *resultSet = [self.database executeQuery:@"select * from t_student"];

    // 遍历出需要的结果内容
    while (resultSet.next) {
        NSInteger ID = [resultSet intForColumn:@"id"];
        NSString *name = [resultSet objectForColumnName:@"name"];
        NSInteger age = [resultSet intForColumn:@"age"];
        NSString *sax = [resultSet objectForColumnName:@"sax"];

        NSLog(@"id = %ld name = %@, age = %ld, sax = %@", ID, name, age, sax);
    }

    [self.database close];
}

@end

4. FMDB实现多线程操作

 1> 概述

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

 2> 创建操作队列

  使用的初始化方法

+ (instancetype)databaseQueueWithPath:(NSString*)aPath

 3> 把操作打包放在操作队列中

  打包的方法

- (void)inTransaction:(void (^)(FMDatabase *db, BOOL *rollback))block

  在 Block 中添加串行队列

 4> 实例代码

#pragma mark - 以队列的形式添加很多学生
- (IBAction)insertManyStudent:(id)sender
{
    // 以队列的形式添加学生是FMDB比较常用的添加方式
    // FMDB不支持多个线程同时操作,一般使用串行方式实现相关的操作

    [self.database open];

    // 第一步:创建操作队列
    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:self.filePath];

    // 标识:记录是否操作成功
    __block BOOL isSucceed = YES;

    // 第二步:把操作打包放在操作队列中
    NSString *insertSql = @"insert into t_studen(name, age, sax) values(?, ?, ?)";

    [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        // 串行队列
        isSucceed &= [db executeUpdate:insertSql, @"隔壁老王", @38, @"男"];
        isSucceed &= [db executeUpdate:insertSql, @"Black", @18, @"女"];
        isSucceed &= [db executeUpdate:insertSql, @"-1", @23, @"男"];

        if (!isSucceed) {

            // block 返回的参数rollback进行处理(BOOL类型的指针)
            *rollback = YES;
            return;
        } else {
            NSLog(@"以队列的形式添加成功");
        }
    }];

    [self.database close];
}
时间: 2024-10-05 02:33:04

iOS学习47之第三方-FMDB的相关文章

IOS学习:常用第三方库(GDataXMLNode:xml解析库)

IOS学习:常用第三方库(GDataXMLNode:xml解析库) 分类: ios开发学习2013-05-30 09:45 4443人阅读 评论(0) 收藏 举报 iOSXMLGDataXMLNode 一.GDataXMLNode说明 GDataXMLNode是Google提供的用于XML数据处理的类集.该类集对libxml2--DOM处理方式进行了封装,能对较小或中等的xml文档进行读写操作且支持XPath语法. 使用方法: 1.获取GDataXMLNode.h/m文件,将GDataXMLNo

iOS学习46之第三方的安装和使用(通用方法)

本文主要说明CocoaPods的安装步骤.使用说明和常见的报错即解决方法. 1. CocoaPods 1>  CocoaPods简介 CocoaPods是一个用来帮助我们管理第三方依赖库的工具. 在开发iOS应用时,会经常使用第三方类库,比如SDWebImage.AFNetworking等等,手动的下载与添加类库非常麻烦,通过CocoaPods可以便捷的下载与管理第三方类库. 使用CocoaPods的目的是让我们能自动化的.集中的.直观的管理第三方开源库. 官方链接:https://cocoap

iOS学习之常用第三方框架总结(经典/必看)

写iOS 程序的时候往往需要很多第三方框架的支持,可以大大减少工作量,讲重点放在软件本身的逻辑实现上. GitHub 里面有大量优秀的第三方框架,而且 License 对商业很友好.一下摘录一下几乎每个项目都想集成的几个框架. SDWebImageView 1. Mantle Mantle 让我们能简化 Cocoa 和 Cocoa Touch 应用的 model 层.简单点说,程序中经常要进行网络请求,请求到得一般是 json 字符串,我们一般会建一个 Model 类来存放这些数据.这就要求我们

【原】iOS学习之Masonry第三方约束

1.Masonry概述 目前最流行的Autolayout第三方框架 用优雅的代码方式编写Autolayout 省去了苹果官方恶心的Autolayout代码 大大提高了开发效率 框架地址:https://github.com/SnapKit/Masonry 2.常用方法 这个方法只会添加新的约束 [blueView mas_makeConstraints:^(MASConstraintMaker *make) { }]; 这个方法会将以前的所有约束删掉,添加新的约束 [blueView mas_r

iOS学习笔记(十六)——数据库操作(使用FMDB)

iOS中原生的SQLite API在使用上相当不友好,在使用时,非常不便.于是,就出现了一系列将SQLite API进行封装的库,例如FMDB.PlausibleDatabase.sqlitepersistentobjects等,FMDB (https://github.com/ccgus/fmdb) 是一款简洁.易用的封装库,这一篇文章简单介绍下FMDB的使用. 在FMDB下载文件后,工程中必须导入如下文件,并使用 libsqlite3.dylib 依赖包. FMDB同时兼容ARC和非ARC工

iOS 学习资料

(适合初学者) 本文资料来源于GitHub 一.视频教程(英文) Developing iOS 7 Apps for iPhone and iPad斯坦福开放教程之一, 课程主要讲解了一些 iOS 开发工具和 API 以及 iOS SDK 的使用, 属于 iOS 基础视频 iPad and iPhone Application Development该课程的讲师 Paul Hegarty 是斯坦福大学软件工程学教授, 视频内容讲解得深入, 权威, 深受好评 Advanced iPhone Dev

iOS 学习资料整理集合

视频教程(英文) Developing iOS 7 Apps for iPhone and iPad 斯坦福开放教程之一, 课程主要讲解了一些 iOS 开发工具和 API 以及 iOS SDK 的使用, 属于 iOS 基础视频 iPad and iPhone Application Development 该课程的讲师 Paul Hegarty 是斯坦福大学软件工程学教授, 视频内容讲解得深入, 权威, 深受好评 Advanced iPhone Development - Fall 2010 i

iOS 学习资料整理(转)

视频教程(英文) 视频教程(中文) 书籍 博客 文章 相关网站 社区 工具/插件 GitHub Top 50 简介 邮件订阅 文档 指南 Awesome 系列 知乎上的讨论 Quora 上的讨论 贡献者 License 这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的目前所处的位置. 该文档会持续更新, 同时也欢迎更多具有丰富经验的 iOS 开发

【超齐全】iOS 学习资料整理

好赶货,收藏.原文iOS 学习资料整理 这份学习资料是为 iOS 初学者所准备的, 旨在帮助 iOS 初学者们快速找到适合自己的学习资料, 节省他们搜索资料的时间, 使他们更好的规划好自己的 iOS 学习路线, 更快的入门, 更准确的定位的目前所处的位置. 该文档会持续更新, 同时也欢迎更多具有丰富经验的 iOS 开发者将自己的常用的一些工具, 学习资料, 学习心得等分享上来, 我将定期筛选合并, 文档尚有一些不完善之处, 也请不吝指出, 感谢您对 iOS 所做的贡献, 让我们一起把国内的 iO