美文网首页Swift
fmdb swift版本的封装

fmdb swift版本的封装

作者: jianshudxw | 来源:发表于2019-03-14 22:42 被阅读0次

前言

移动开发经常需要使用 sqlite,对于稍微复杂一点的存储 FMDB 是首选。 一般我们都会对FMDB再进行一个封装使其更适合自己工程的使用。这是我用代码一步一步实现自己的 ios 架构一部分。fmdb 没有swift 版本。但是任然可用。我使用的是 FMDB v2.7.5 具体如何引入工程参考 GitHub

问题

既然要封装FMDB 我就要看看我们要解决哪些问题

  • 业务逻辑需求 (选择多数据库)
  • 数据效率 (多线程)
  • 数据安全 (FMDatabaseQueue)
  • 数据一致性 (transaction)
  • 调用方便
  • 数据库升级

选择多数据库模式

对于拥有游客和用户类型的App,数据有两种选择:

单个库,多张表 每张表都有一个UserId字段区分,表比较大,sql 相对麻烦 ,使用简单
多库多表 通过库区分不同用户,表小,效率更高,使用相对复杂

以前看过微信的数据库好像是多库的。
我这里选择 多库模式

ATTACH DATABASE 'dbPath' as 'dbName'
DETACH DATABASE 'dbName'
  • 主要用这两个语句创建/分离数据库。注意dbPath上的引号不要遗漏。
  • 默认是游客数据库id为0,user 登录成功就 attach 到user 数据库
  • 因为切换用户要 diattach ,一次程序启动只有 游客和某一个具体的数据库可用。
  • 登录用户可以看游客的内容,但游客只能能查看部分登录用户页面。所以不同角色拥有的数据库的表并不相同。
  • 我这里并没有联库查询,那样太复杂。相同的角色拥有相同的表。
    简单的分析我们可以看出,需要分角色,不同角色看的页面不同,表不同。对应的枚举是
enum ResAccessRole: String {
    case Public = "pub"
    case User = "user"
    case All = "all"
}

这里简单点就是登录用户,游客(public),为了代码方便实现有一个All。dbName 就是对应的角色。

  • 更详细的用户切换,我在登陆模块说明。

效率和安全性

关于安全性 FMDB 已经考虑了 ,但是效率问题,需要我们自己管理
FMDatabaseQueue 的内部使用的是 串行队列 同步任务 保证了是线程的安全性,

 _queue = dispatch_queue_create([[NSString stringWithFormat:@"fmdb.%@", self] UTF8String], NULL);

    dispatch_sync(_queue, ^() {
//相关代码
}

数据一致性 transaction

参考我对SQLite的强行研究
这里我主要用这个方法
- (void)inTransaction:(__attribute__((noescape)) void (^)(FMDatabase *db, BOOL *rollback))block;

数据库升级

数据库的升级由数据库模块完成大部分常规的升级,比如增加字段。并放出接口有各个模块实现其特殊的需求。
DBModelVersion 保存每个model 的数据库版本

truct DBModelVersion: HandyJSON {
    var name    :String!
    var version :Int!
}

extension DBModelVersion: DBModel {
    static var dbPrimaryKeys: [String]? { return ["name"] }
    
    static var dbTableName: String {
        return "dbversion"
    }
    
    static var dbColumns: Dictionary<String, DBConstants.DataType> {
        return [
            "name"    : .text,
            "version"     : .integer
        ]
    }
}

对比 version 看是否升级数据库

调用方便

关于 sql 语句的书写我封装了方法 参考sql 语句Swift封装,链式调用

代码实现

基本思路说完了,下面看看具体的代码。代码看源码都很简单,我说说一些主要点。

主要类
  1. DataBaseModule 实现了 ModuleProtocl 主要在数据库模块加载时完成数据库相关设置:配置、创建、升级等。 configDB,clearDBCache,createDB这个几个方法需要banner模式。
  2. DBHelper 数据库操作的具体实现。其他类都是调用这个类里面具体实现。比如:增删改查等。提供了统一的 并行队列:executionQueue。
  3. BaseDao 其他所有模块类的基类比如 USerDao。提供一些基本信息dbName,将回调返回到主线程
  4. SqlStatement sql 语句封装 便于使用
  5. DBProtocol.swift 定义了要实现数据库功能的必要的协议
  6. DBModelVersion 数据表版本数据结构
一些我认为的知识点
  • 定义常量 :struct DBConstants 层次清楚
  • 封装一些容易遗漏的代码 extension FMResultSet 代码更适合使用
  • 模板方法 func queryModel<T: Model>。 oc 很少使用,swift 很好用
  • 注意 可选型的非逃逸闭包, 我写的时候不清楚,总是提示使用不对
看源码

TODO:关于数据库操作的顺序可以分得更细。哪些可以并行,哪些必须安顺序进行。但这个工程比较大。我目前的方案效率对我来说够了。

相关文章

网友评论

    本文标题:fmdb swift版本的封装

    本文链接:https://www.haomeiwen.com/subject/cghduqtx.html