在iOS开发中使用FMDB

2023-10-26

我的第一个应用使用的数据库是操作sqlite3 熟悉了之后 还不愿意换了。说实话这个方法并不是很轻量级,繁琐,复杂的数据读取插入后果就是崩了,我知道很大一部分原因是因为我的线程没处理好、出现死锁、逻辑混乱导致的。所以我想使用更轻量级的数据库,逻辑更清晰,这样会降低程序的复杂度,易于维护、赋予程序健壮性。

我在网上找到一个比较好的资源 贴在下边 ,当自己有空了会diy成自己的。

http://lsl1991bsdk.blog.163.com/blog/static/207912440201332552634316/

前言

SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库。iOS SDK很早就支持了SQLite,在使用时,只需要加入 libsqlite3.dylib 依赖以及引入 sqlite3.h 头文件即可。但是,原生的SQLite API在使用上相当不友好,在使用时,非常不便。于是,开源社区中就出现了一系列将SQLite API进行封装的库,而FMDB (https://github.com/ccgus/fmdb) 则是开源社区中的优秀者。

FMDB在使用上相当方便。以下是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
NSString* docsdir = [NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
NSString* dbpath = [docsdir stringByAppendingPathComponent:@"user.sqlite"];
FMDatabase* db = [FMDatabase databaseWithPath:dbpath];
[db open];
FMResultSet *rs = [db executeQuery:@"select * from people"];
while ([rs next]) {
    NSLog(@"%@ %@",
        [rs stringForColumn:@"firstname"],
        [rs stringForColumn:@"lastname"]);
}
[db close];

可以看到,使用FMDB后的数据库代码清晰明了,比原生的API优雅多了。另外,FMDB同时兼容ARC和非ARC工程,会自动根据工程配置来调整相关的内存管理代码。

使用说明

该使用说明主要翻译自fmdb的github项目说明文档: https://github.com/ccgus/fmdb

引入相关文件

首先将FMDB从github上clone下来,然后将以下文件copy到你的工程中:

1
2
3
4
5
6
7
8
9
10
FMDatabase.h
FMDatabase.m
FMDatabaseAdditions.h
FMDatabaseAdditions.m
FMDatabasePool.h
FMDatabasePool.m
FMDatabaseQueue.h
FMDatabaseQueue.m
FMResultSet.h
FMResultSet.m

建立数据库

建立数据库只需要如下一行即可,当该文件不存在时,fmdb会自己创建一个。如果你传入的参数是空串:@”” ,则fmdb会在临时文件目录下创建这个数据库,如果你传入的参数是 NULL,则它会建立一个在内存中的数据库。

1
FMDatabase *db = [FMDatabase databaseWithPath:@"/tmp/tmp.db"];

打开数据库

使用如下语句,如果打开失败,可能是权限不足或者资源不足。通常打开完操作操作后,需要调用close方法来关闭数据库。

1
2
3
4
5
6
7
8
if (![db open]) {
    // error 
    return;
}
// some operation
// ...
[db close];

执行更新操作

除了Select操作之外,其它的都是更新操作。更新操作使用如下方法,如果有错误,可以用error参数中获得。

1
-[FMDatabase executeUpdate:error:withArgumentsInArray:orVAList:]

执行查询操作

查询操作示例如下。注意:即使操作结果只有一行,也需要先调用FMResultSet的next方法。

1
2
3
4
5
6
7
8
9
FMResultSet *s = [db executeQuery:@"SELECT * FROM myTable"];
while ([s next]) {
    //retrieve values for each record
}
FMResultSet *s = [db executeQuery:@"SELECT COUNT(*) FROM myTable"];
if ([s next]) {
    int totalCount = [s intForColumnIndex:0];
}

FMDB提供如下多个方法来获取不同类型的数据:

1
2
3
4
5
6
7
8
9
10
11
intForColumn:
longForColumn:
longLongIntForColumn:
boolForColumn:
doubleForColumn:
stringForColumn:
dateForColumn:
dataForColumn:
dataNoCopyForColumn:
UTF8StringForColumnIndex:
objectForColumn:

通常情况下,你并不需要关闭FMResultSet,因为相关的数据库关闭时,FMResultSet也会被自动关闭。

数据参数

通常情况下,你可以按照标准的SQL语句,用?表示执行语句的参数,如:

1
INSERT INTO myTable VALUES (?, ?, ?)

然后,可以我们可以调用executeUpdate方法来将?所指代的具体参数传入,通常是用变长参数来传递进去的,如下:

1
2
NSString *sql = @"insert into User (name, password) values (?, ?)";
[db executeUpdate:sql, user.name, user.password];

这里需要注意的是,参数必须是NSObject的子类,所以象int,double,bool这种基本类型,需要封装成对应的包装类才行,如下所示:

1
2
3
4
// 错误,42不能作为参数
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", 42];
// 正确,将42封装成 NSNumber 类
[db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:42]];

线程安全

如果我们的app需要多线程操作数据库,那么就需要使用FMDatabaseQueue来保证线程安全了。 切记不能在多个线程中共同一个FMDatabase对象并且在多个线程中同时使用,这个类本身不是线程安全的,这样使用会造成数据混乱等问题。

使用FMDatabaseQueue很简单,首先用一个数据库文件地址来初使化FMDatabaseQueue,然后就可以将一个闭包(block)传入inDatabase方法中。 在闭包中操作数据库,而不直接参与FMDatabase的管理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 创建,最好放在一个单例的类中
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:aPath];
// 使用
[queue inDatabase:^(FMDatabase *db) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
    FMResultSet *rs = [db executeQuery:@"select * from foo"];
    while ([rs next]) {
        // …
    }
}];
// 如果要支持事务
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:1]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:2]];
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:3]];
    if (whoopsSomethingWrongHappened) {
        *rollback = YES;
        return;
    }
    // etc…
    [db executeUpdate:@"INSERT INTO myTable VALUES (?)", [NSNumber numberWithInt:4]];
}];

工具

为了查看Sqlite中的数据,一个好的图形化界面的数据库管理程序是必不可少的。mysql有phpMyAdmin,那么sqlite呢?

我主要使用的是Firefox的一个名为SQLite Manager的插件,安装此插件后,可以直接打开后缀名为sqlite的数据库文件。SQLite Manager提供一个图形化的界面来执行数据查询或更改操作。如下图所示:

在iOS开发中使用FMDB - lsl1991bsdk - lsl1991bsdk的博客

总结

FMDB将SQLite API进行了很友好的封装,使用上非常方便,对于那些使用纯Sqlite API来进行数据库操作的app,可以考虑将其迁移到基于FMDB上,这对于以后数据库相关功能的开发维护,可以提高不少效率。

我在学习fmdb的时候做了一个小工程用于练习,我把它放到github上了。感兴趣的可以自行下载:https://github.com/tangqiaoboy/FmdbSample

转载于:https://www.cnblogs.com/someonelikeyou/p/3768443.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在iOS开发中使用FMDB 的相关文章

  • 天梯赛 一至十二届题解合集(最简洁规范题解)

    l1和l2已全部更新完毕 l3更新大概1 3 有更好的解法的大佬请在评论区指出 题解 第一届 点我 题解 第二届 点我 题解 第三届 点我 题解 第四届 点我 题解 第五届 点我 题解 第六届 点我 题解 第七届 点我 题解 第八届 点我

随机推荐

  • (网络安全数据集一)美国国家安全漏洞库 NVD-CVE信息解读 和常用漏洞库

    NVD中CVE信息解读 最近要用到这方面的数据 就对NVD中的一小段CVE信息选取做了简单的理解 有错的地方请大佬指正 一个完整的CVE信息 包含 六部分 元数据 漏洞影响软件信息 漏洞问题类型 参考和漏洞介绍 configurations
  • Spring Boot 中的 @SendTo 注解

    Spring Boot 中的 SendTo 注解 在 Spring Boot 中 SendTo 注解是一个非常有用的注解 它可以用于实现 WebSocket 的消息转发功能 本文将介绍 SendTo 注解的原理 使用方法和示例代码 什么是
  • Sophus库:对SO(3)和SE(3)的构建及扰动模型搭建

    简介 使用Eigen库中Geometry模块能够实现对 S O 3 SO 3 SO 3 S
  • 微信开发者工具的版本控制

    注意事项 拉取代码时 应先关闭所有的编辑器代码页面 清理版本管理工具里的工作区 保存到本地 不管什么时候 需要把代码提交到线上的请先拉取一下线上代码 一 提交代码流程 先在 微信开发者工具 的 版本管理 中把代码存储在本地分支上 拉取线上分
  • 用js实现简单的满屏跳动的心

    用js实现简单的满屏跳动的心
  • 实施MES系统的成功率只有50%,你知道为什么吗?

    MES系统可以称之为生产制造产业生产和管理方法实现代化的管理中心 假如可以非常好的执行和运用MES 那么将有益于提升公司的生产率 降低消耗成本 但为什么会有些公司MES执行实际效果不佳呢 原因之一 我国制造业存在管理方法基础的先天发育不足
  • Android中LCD背光驱动

    分类 Linux驱动 Android系统 2013 06 17 16 28 287人阅读 评论 0 收藏 举报 目录 Android的Setting Android的背光JNI层 Android的背光HAL层 Linux的背光内核层 Lin
  • 【web基础】html常用标签+作品展示

    前言 小亭子正在努力的学习编程 接下来将开启javaEE的学习 分享的文章都是学习的笔记和感悟 如有不妥之处希望大佬们批评指正 同时如果本文对你有帮助的话 烦请点赞关注支持一波 感激不尽 说明 此部分是java web基础知识 学的不深 仅
  • python爬虫万能模板

    以下是一个简单的 Python 爬虫模板 可以用于爬取网页数据 python import requests from bs4 import BeautifulSoup 设置请求头 模拟浏览器访问 headers User Agent Mo
  • kubectl命令详解

    目录 一 kubectl命令详解 1 查看某个资源的详细信息 kubectl describe pod pod name n nameapace 2 查看指定命名空间中pod的基本信息 kubectl get pods n namespac
  • kubernetes自建单节点elasticsearch ,用做数据库

    apiVersion v1 kind ConfigMap metadata name es configmap namespace kube system data elasticsearch yml cluster name NAMESP
  • redis key以目录展示的算法 以及其他redis相关

    文章目录 前言 一 redis相关 二 目录展示算法 结果展示 前言 一般在开发中使用redis时 都会使用冒号进行key的分割 例如login token admin等等 最近被要求编写可视化redis管理的工具 要以树形文件夹目录展示r
  • 环境类传感器介绍

    经过前几篇的原理讲解 大家对市面上类似气体 PM2 5 火焰呀这类传感器有一定的了解 但是到采购环节就迷茫了 毕竟市面上的产品五花八门 挑的眼花缭乱 今天给大家介绍几款简单的传感器 如果大家有别的传感器 也可以采用 甲醛检测 ZE08 CH
  • unity2017Progressive Lightmapper,Navmesh,Timeline三大新特性总结

    今天看了刘国柱的unity2017新特性 keynote大会三大核心详解视频课程 以免忘记 所以总结了下 想要具体了解的话可以去51cto观看刘国柱的视频 一 更强大的图像处理 1 Progressive LightMapper 2 新灯光
  • 如何计算Map

    一 VOC07 11点计算法 在VOC2010以前 只需要选取当Recall gt 0 0 1 0 2 1共11个点时的Precision最大值 然后AP就是这11个Precision的平均值 在VOC2010及以后 需要针对每一个不同的R
  • MySQL查询条件中字符串包含空格的问题

    2013 11 27 wcdj 问题 最近在联调某个业务时发现使用的签名总是验证不过 在MySQL中查询了该业务的私钥配置和业务侧的配置是一样的 问题就出在SQL查询这里 最后将配置导出到本地发现私钥后面多了一个空格 将空格删除然后签名计算
  • table嵌套table

  • QT 打开txt文件以及出现的乱码问题

    在用QT实现记事本打开功能时 在导入txt文件后会出现乱码问题 这时需要对导入文件编码进行设置 代码如下 void MainWindow open QString fileName 弹出打开文件对话框 fileName QFileDialo
  • Vb仓库管理系统与实现(论文+源代码+开题报告+外文翻译+文献综述)

    随着科学技术的不断提高 计算机科学不断发展 其强大的功能已经被人们深刻认识 它已经进入了人类社会的各个领域并发挥着越来越重要的作用 作为计算机应用的一部分 使用计算机对产品库存信息进行管理 是一直必然的趋势 本文主要分析了库存管理系统的一些
  • 在iOS开发中使用FMDB

    我的第一个应用使用的数据库是操作sqlite3 熟悉了之后 还不愿意换了 说实话这个方法并不是很轻量级 繁琐 复杂的数据读取插入后果就是崩了 我知道很大一部分原因是因为我的线程没处理好 出现死锁 逻辑混乱导致的 所以我想使用更轻量级的数据库