zoukankan      html  css  js  c++  java
  • 第三方库FMDB的使用

    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数据库文件路径.
    •  1 //第一步:创建sql语句(创建学生表)
       2     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)";
       3     
       4     //第二步:找到存储路径
       5     NSString *document = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
       6     NSLog(@"%@", document);
       7     self.filePath = [document stringByAppendingPathComponent:@"student.sqlite"];
       8     NSLog(@"%@", self.filePath);
       9     //第三步:使用路径初始化FMDB对象(其实到这步,数据库的创建就算是完成了)
      10     self.dataBase = [FMDatabase databaseWithPath:self.filePath];
      11     //第四步:数据库执行相关操作
      12     //需要判断数据库打开的时候才进行执行语句,才开始创建表.
      13     if ([self.dataBase open]) {
      14         
      15         BOOL result = [self.dataBase executeUpdate:createSql];
      16         if (result) {
      17             NSLog(@"建表成功");
      18         } else {
      19             NSLog(@"建表失败");
      20         }
      21     }
      22     //上面的步骤是在数据库中创建了学生表
      23     //第五步:关闭数据库(为了节约资源,随即使用完了就关闭)
      24     [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)]]; 

    代码示例:

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

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

     1 #pragma mark - 修改
     2 - (IBAction)updateAction:(id)sender {
     3  //第一步:打开数据库
     4     [self.dataBase open];
     5    BOOL result = [self.dataBase executeUpdate:@"update t_student set name = ? where name = ?", @"孟玲旭", @"MBBoy"];
     6     if (result) {
     7         NSLog(@"更改成功");
     8     } else {
     9         NSLog(@"更改失败%d", result);
    10     }
    11     
    12     [self.dataBase close];
    13 }
    14 
    15 #pragma mark - 删除
    16 - (IBAction)deleteAction:(id)sender {
    17     [self.dataBase open];
    18     //执行sql语句
    19     BOOL result = [self.dataBase executeUpdate:@"delete from t_student where name = ?", @"孟玲旭"];
    20     if (result) {
    21         NSLog(@"删除成功");
    22     } else {
    23         NSLog(@"删除失败%d", result);
    24     }
    25     [self.dataBase close];
    26 }

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

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

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

    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实际上是在多线程中的串行队列中使用,并不支持并行队列

    示例代码:

     1 #pragma mark - 以队列的形式添加数据,是FMDB比较常用的形式
     2 - (IBAction)insertStudentByLineAtion:(id)sender {
     3     //以队列的形式添加数据是FMDB比较常用的添加方式
     4     [self.dataBase open];
     5     //FMDB不支持多个线程同时操作,所以一般以串行的方式实现相关操作
     6     //第一步:创建操作队列
     7     FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:self.filePath];
     8     //标识:记录是否操作成功
     9     __block BOOL isSucceed = YES;  //第一个队列语句的isSucceed根据
    10     //第二步:把所需要的事件打包放在操作队列中
    11     [queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    12         //串行队列 && isSucceed 是依据上一条语句是否成功插入,否则不执行本条语句.一个执行完,下一个才执行.
    13         isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"隔壁老王", @"38", @""] && isSucceed;
    14         isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"赵符壹", @"438", @"未知"] && isSucceed;
    15         isSucceed = [db executeUpdate:@"insert into t_student(name, age, sex) values (?,?,?)", @"AJAR", @"18", @""] && isSucceed;
    16         //如果有错误,就会将它返回
    17         if (!isSucceed) {
    18             //block返回的参数rollback进行处理(bool类型的指针)
    19 //有错误,直接返回,不再继续往下执行
    20             *rollback = YES;
    21             return ;
    22         }
    23     }];
    24     [self.dataBase close];
    25 }
  • 相关阅读:
    我用Python爬虫挣钱的那点事
    猿人学 . 爬虫逆向高阶课
    Python中实用却不常见的小技巧
    Python内存数据序列化到硬盘上哪家强
    利用setuptools发布Python程序到PyPI,为Python添砖加瓦
    配置tmux在机器重启后自动恢复tmux工作现场,告别重启恐惧症
    用python实现新词发现程序——基于凝固度和自由度
    学习笔记:Python序列化常用工具及性能对比
    浅谈自然语言在科技时代的运用
    python学习笔记:建立一个自己的搜索引擎
  • 原文地址:https://www.cnblogs.com/lovebugssun/p/5543141.html
Copyright © 2011-2022 走看看