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
    使用手续相似,创立数据库路线,获得数据库路线,展开数据库,然后对数据库实行增、删、改、查操作,最终关闭数据库。

1. FMDB简介

 1> FMDB—实践更新

  一切不是SELECT命令的吩咐都实属更新。那蕴涵CREAT,UPDATE,INSERT,ALTE凯雷德,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。  

  轻松的话,只要不是以 SELECT
初始的指令都以翻新命令。

     
实施更新再次来到三个BOOL值。YES代表实施成功,不然表示有不当。你能够调用
-lastErrorMessage 和 -lastErrorCode方法来博取愈来愈多音讯。

FMDB框架中驷不及舌的框架类
  • FMDatabase
    • FMDatabase对象就代表二个独门的SQLite数据库,用来进行SQL语句
  • FMResultSet
    • 运用FMDatabase施行查询后的结果集
  • FMDatabaseQueue
    • 用于在多线程中施行多个查询或更新,它是线程安全的

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

  打包的章程

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

  在 Block 中加多串行队列

 1> FMDB—实施更新

  一切不是SELECT命令的指令都算得更新。那包蕴CREAT,UPDATE,INSERT,ALTE猎豹CS6,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。  

  简单的讲,只要不是以 SELECT
初步的一声令下都以革新命令。

     
实施更新重临二个BOOL值。YES表示实践成功,不然表示有荒唐。你能够调用
-lastErrorMessage 和 -lastErrorCode方法来得到越来越多音讯。

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

  打包的措施

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

  在 Block 中增加串行队列

使用FMDatabaseQueue类完成四线程操作

在八个线程中并且采纳叁个FMDatabase实例是不明智的。未来您可感觉每种线程创造二个FMDatabase对象,不要让四个线程分享同一个实例,他不或许在八个线程中同事使用。不然程序会时有时崩溃也许报告足够。所以,不要
开端化FMDatabase对象,然后在多少个线程中采取。那时候,我们就须要使
用FMDatabaseQueue来创制队列实践专门的学问。

- (void)createDatabaseQueue {
    int age1 = arc4random_uniform(100);
    int age2 = arc4random_uniform(100);
    int age3 = arc4random_uniform(100);

    NSString *name1 = [NSString stringWithFormat:@"chen - %d",age1];
    NSString *name2 = [NSString stringWithFormat:@"chen - %d",age2];
    NSString *name3 = [NSString stringWithFormat:@"chen - %d",age3];

    // 1.获得数据库文件的路径
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    NSString *fileName = [doc stringByAppendingPathComponent:@"student.sqlite"];
    //1.创建队列
    FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:fileName];

    __block bool whoopsSomethingWrongHappened = true;

    //2.把任务包装到事务里
    [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
        whoopsSomethingWrongHappened = [db executeUpdate:@"insert into t_student(name,age) values (?,?);" withArgumentsInArray:@[name1,@(age1)]];
        whoopsSomethingWrongHappened = [db executeUpdate:@"insert into t_student(name,age) values (?,?);" withArgumentsInArray:@[name2,@(age2)]];
        whoopsSomethingWrongHappened = [db executeUpdate:@"insert into t_student(name,age) values (?,?);" withArgumentsInArray:@[name3,@(age3)]];

        // 如果有错误,则返回
        if (!whoopsSomethingWrongHappened) {
            *rollback = YES;
            return;
        }
    }];
}

本文参照他事他说加以考察陈向阳哈数据库第三方框架FMDB详细批注,极其多谢该小编.

 1> 概述

  • iOS 中原生的 SQLite API 在进展数据存款和储蓄的时候,供给运用 C语言
    中的函数,操作比较繁琐。于是,就出现了一密密麻麻将SQLite API
    实行打包的库,比方 FMDB、PlausibleDatabase、SQLitePersistentObjects
    等。  

  • FMDB 是一款轻易、易用的封装库。由此,在此间推荐应用第三方框架
    FMDB,它是对 libsqlite3 框架的包裹,用起来的步骤与 SQLite
    使用类似,何况它对于多线程的出现操作举行了管理,所以是线程安全的。

  ② 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);
    }

 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"]];

  以上的主意我们能够依据本人的习贯和须要接纳一种就可以。

数据库创立

成立FMDatabase对象时参数为SQLite数据库文件路线,该路径能够是以下三种办法之一

  • 文件路线。该公文路线无需真实存在,固然不真实会自动创造
  • 空字符串(@“”)。表示会在一时目录创制贰个空的数据库,当FMDatabase连接关闭时,文件也会被去除
  • NULL。将创建多个内在数据库,同样的,当FMDatabase连接关闭时,数据将会被灭绝

 1> FMDB—施行更新

  一切不是SELECT命令的指令都说是更新。那富含CREAT,UPDATE,INSERT,ALTE本田CR-V,BEGIN,COMMIT,DETACH,DELETE,DROP,END,EXPLAIN,VACUUM,REPLACE等。  

  简单的话,只要不是以 SELECT 初叶的一声令下都以翻新命令。

     
施行更新重返二个BOOL值。YES代表试行成功,不然表示有荒唐。你能够调用
-lastErrorMessage 和 -lastErrorCode方法来获得更加多信息。

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

  打包的措施

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

  在 Block 中加多串行队列

  ① 概述  

  SELECT
命令正是查询,实施查询的法门是以 -excuteQuery 初步的。

  实行查询时,若是成功重回 FMResultSet 对象,错误重回 nil 。与实践更新同样,帮助接纳 NSError 参数。

  同有的时候候,你也足以使用 -lastErrorCode 和 -lastErrorMessage 获知错误消息。

初识 FMDB


iOS中原生的SQLite
API在开始展览数量存款和储蓄的时候,供给选拔C语言中的函数,操作相比较麻烦。于是,就涌出了一雨后玉兰片将SQLite
API实行包装的库,比方FMDBPlausibleDatabasesqlitepersistentobjects等。

FMDB是一款轻便、易用的封装库。因而,在此地推荐应用第三方框架FMDB,它是对libsqlite3框架的卷入,用起来的步调与SQLite使用类似,並且它对于三十二线程的面世操作实行了拍卖,所以是线程安全的。


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

威澳门尼斯人36366com, 1> 概述

  • 若果选择中动用了十二线程操作数据库,那么就供给选拔FMDatabaseQueue
    来保管线程安全了。 应用中不得在四个线程中一道选取五个 FMDatabase
    对象操作数据库,那样会孳生数据库数据错乱(比如利用七个线程同一时候对数据库进行更新和查找)。

  • 四个线程更新一样的能源导致数据竞争时利用等待队列(等待未来奉行的处理终结)。

  • 以队列的花样丰富是 FMDB
    相比较常用的丰硕格局。

  • FMDB
    不协助四个线程同期操作,一般采纳串行情势达成相关的操作。

 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

数据库使用FMDB框架代码操作

  • 利用FMDataBase类建构数据库

- (void)createDataBase {
    // 1.获得数据库文件的路径
    NSString *doc = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

    NSString *fileName = [doc stringByAppendingPathComponent:@"student.sqlite"];

    // 2.获得数据库
    FMDatabase *db = [FMDatabase databaseWithPath:fileName];
    self.db = db;

    // 3.使用如下语句,如果打开失败,可能是权限不足或者资源不足,通常打开完操作操作后,需要调用 close 方法来关闭数据库。
    // 在和数据库交互 之前,数据库必须是打开的。如果资源或权限不足无法打开或创建数据库,都会导致打开失败。
    if ([db open]) {
        // 4.创建表
        bool result = [db executeUpdate:@"create table if not exists t_student(id integer PRIMARY KEY AUTOINCREMENT, name text not null, age integer not null)"];
        if (result) {
            NSLog(@"创建表格成功");
        }
    }
}
  • 查看 sql 表
  1. 基于路径fileName在Finder中找出.sqlite文件,并复制到桌面
  2. 在 App Store 下载 Datum free 免费软件,然后张开.sqlite 文件就可以.
![](https://upload-images.jianshu.io/upload_images/1653926-d90fd7e76d777c02.png)

t\_student.sqlite 表

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注