SQLite数据库框架之FMDB

什么是FMDB

FMDB是iOS平台的SQLite数据库框架,FMDB以OC的方式封装了SQLite的C语言API。对比苹果自带的Core Data框架,更加轻量级和灵活,使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码。并且FMDB提供了多线程安全的数据库操作方法,能有效地防止数据混乱。

如何集成FMDB?

这里我只写swift中的集成方式,Objective-C类似,只是不需要添加Swift extensions和桥接。

GitHub地址:https://github.com/ccgus/fmdb

方式一:

下载后将fmdb-master/src/fmdb和fmdb-master/src/extra/Swift extensions拖入项目中,添加系统库文件libsqlite3.tbd。如下图所示:

方式二:

通过CocoaPods添加,但是不推荐这种方式,因为这不是官方的。

 
1
2
use_frameworks!
pod 'FMDB', :git => 'https://github.com/robertmryan/fmdb.git'

FMDB核心类

FMDatabase: 一个FMDatabase表示一个sqlite数据库,所有对数据库的操作都是通过这个类。

executeStatements: 执行多条sql。

executeQuery: 执行查询语句。

executeUpdate: 执行除查询以外的语句,create, drop, insert, delete, update。

FMDatabaseQueue: 内部封装FMDatabase和串行queue,用于多线程操作数据库,并且提供事务,建议使用这个。

inDatabase: 参数是一个闭包,在闭包里面可以获得FMDatabase对象。

inTransaction: 使用事务。

FMResultSet: 查询的结果集。

通过字段名称获取字段值。

如何使用FMDB?

一、创建表

使用FMDB和使用AFNetworking类似,最好单独创建一个工具类,使用单例进行数据库操作。

新建JFSQLiteManager类,继承NSObject。在这个类中重写构造方法创建FMDatabaseQueue对象,并创建一张数据表JF_Person。表中有4个字段,分别是id(主键)、name、age、height。

 
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import UIKit
 
class JFSQLiteManager: NSObject {
    
    /// 创建单例
    static let shareManager = JFSQLiteManager()
    
    /// 数据库名称
    private let dbName = "person.db"
    
    /// FMDatabaseQueue对象,用于操作数据库
    let dbQueue: FMDatabaseQueue
    
    // 构造方法
    override init() {
        
        // 获取沙盒路径
        let documentPath = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true).last!
        
        // 拼接数据库完整路径
        let dbPath = (documentPath as NSString).stringByAppendingPathComponent(dbName)
        
        // 创建FMDatabaseQueue对象,会自动打开数据库,并创建一个串行队列
        dbQueue = FMDatabaseQueue(path: dbPath)
        
        super.init()
        
        // 创建数据表
        createTable("JF_Person")
    }
    
    // 创建数据表 - parameter tbName: 表名
    private func createTable(tbName: String) {
        
        // sql语句
        let sql = "CREATE TABLE IF NOT EXISTS \(tbName) ( \n" +
        "id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \n" +
        "name TEXT, \n" +
        "age INTEGER, \n" +
        "height REAL \n" +
        ");"
        
        // db表示一个数据库
        dbQueue.inDatabase { (db) -> Void in
            
            // 执行sql语句,创建一张表。返回Bool类型是否创建成功
            if db.executeUpdate(sql) {
                print("建表成功")
            } else {
                print("建表失败")
            }
        }
    }
    
}

然后在AppDelegate中调用这个单例,测试我们的代码

 
1
JFSQLiteManager.shareManager

显示 建表成功

二、删除表

在JFSQLiteManager类中实现删除表的方法,删除指定表名的数据表。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    // 删除指定数据库 - parameter tbName: 表名
    func dropTable(tbName: String) {
        
        // sql语句
        let sql = "DROP TABLE \(tbName);"
        
        // db表示一个数据库
        dbQueue.inDatabase { (db) -> Void in
            
            // 执行sql语句,创建一张表。返回Bool类型是否创建成功
            if db.executeUpdate(sql) {
                print("删除表成功")
            } else {
                print("删除表失败")
            }
        }
    }

然后在AppDelegate中调用这个方法,测试我们的代码

 
1
JFSQLiteManager.shareManager.dropTable("JF_Person")

显示 删除表成功

三、增加数据

在JFSQLiteManager类中实现添加数据的方法,插入一条测试数据。这里只是测试学习,所以SQL语句就直接写死了。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    // 添加数据
    func insertData() {
        
        // sql语句
        let sql = "INSERT INTO JF_Person (name, age, height) VALUES (?, ?, ?);"
        
        JFSQLiteManager.shareManager.dbQueue.inDatabase { (db) -> Void in
            if db.executeUpdate(sql, "7ag", 23, 1.95) {
                
                print("插入数据成功")
                
                // 获取插入数据的主键
                let id = db.lastInsertRowId()
                print("插入数据的id: \(id)")
            }
        }
    }

然后在AppDelegate中调用这个方法,测试我们的代码

 
1
JFSQLiteManager.shareManager.insertData()

显示 插入数据成功 插入数据的id: 1

四、删除数据

在JFSQLiteManager类中实现删除数据的方法,删除id = 1的数据。这里只是测试学习,所以SQL语句就直接写死了。

 
1
2
3
4
5
6
7
8
9
10
11
12
13
    // 删除数据
    func deleteData() {
        
        // sql语句
        let sql = "DELETE FROM JF_Person WHERE id = 1;"
        
        JFSQLiteManager.shareManager.dbQueue.inDatabase { (db) -> Void in
            if db.executeUpdate(sql) {
                
                print("删除数据成功")
            }
        }
    }

然后在AppDelegate中调用这个方法,测试我们的代码

 
1
JFSQLiteManager.shareManager.deleteData()

显示 删除数据成功

五、修改数据

上面一步我们把添加的数据给删除,所以我们需要再次调用添加数据的方法,添加一条数据以供我们学习测试使用。

在JFSQLiteManager类中实现更新数据的方法,更新id = 1的数据。这里只是测试学习,所以SQL语句就直接写死了。

 
1
2
3
4
5
6
7
8
9
10
11
12
    // 更新数据
    func updateData() {
        
        // sql
        let sql = "UPDATE JF_Person SET name = '6ag', age = 24, height = 1.92 WHERE id = 1;"
        JFSQLiteManager.shareManager.dbQueue.inDatabase { (db) -> Void in
            if db.executeUpdate(sql) {
                
                print("更新数据成功")
            }
        }
    }

然后在AppDelegate中调用这个方法,测试我们的代码

 
1
JFSQLiteManager.shareManager.updateData()

显示 更新数据成功 !

六、查找数据

上面增、删、改中,我们执行sql语句的方法都是使用executeUpdate。但是查找数据,我们就必须使用executeQuery了。其实不管是神马操作,改变的基本都是SQL语句而已。这一点比起C语言的sqlite API来说,简直是太方便了。如果对于SQL语句不是很熟悉也没关系,在下已经为各位大神准备好了常用SQL语句:http://blog.6ag.cn/1227.html

在JFSQLiteManager类中实现更新数据的方法,查询JF_Person表中所有记录的id,name,age,height字段的值。这里只是测试学习,所以SQL语句就直接写死了。

 
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
29
30
    // 查询数据
    func queryData() {
        
        // sql
        let sql = "SELECT id, name, age, height FROM JF_Person;"
        
        JFSQLiteManager.shareManager.dbQueue.inDatabase { (db) -> Void in
            guard let result = db.executeQuery(sql) else {
                print("没有查询到数据")
                return
            }
            
            // 获取查询结果
            // next() 表示获取一条记录, 返回true表示获取到记录,false表示没有记录。所以我们使用循环来获取所有查询到的数据
            while result.next() {
                
                let id = result.intForColumn("id")
                
                let name = result.stringForColumn("name")
                
                let age = result.intForColumn("age")
                
                let height = result.doubleForColumn("height")
                
                // 打印出查询到的数据
                print("id: \(id), name: \(name), age: \(age), height: \(height)")
                print("------------")
            }
        }
    }

然后在AppDelegate中调用这个方法,测试我们的代码

 
1
JFSQLiteManager.shareManager.queryData()

打印出

id: 1, name: 6ag, age: 24, height: 1.92 

------------

iOS---SQLite数据库框架之FMDB -Swift的更多相关文章

  1. FMDB是iOS平台的SQLite数据库框架

    1.FMDB简介 什么是FMDBFMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 为什么使用FMDB使用起来更加面向对象,省去了很多麻烦.冗余的C语言 ...

  2. SQLite数据库框架--FMDB简单介绍

    1.什么是FMDB FMDB是iOS平台的SQLite数据库框架 FMDB以OC的方式封装了SQLite的C语言API 2.FMDB的优点 使用起来更加面向对象,省去了很多麻烦.冗余的C语言代码 对比 ...

  3. iOS sqlite数据库实现(转)

    转载自:http://www.cnblogs.com/macroxu-1982/archive/2012/10/01/2709960.html 1 实现过程添加libsqlite3组件 选择项目后,在 ...

  4. iOS - SQLite 数据库存储

    1.SQLite 数据库 SQLite 是一种轻型的嵌入式数据库,安卓和 iOS 开发使用的都是 SQLite 数据库.它占用资源非常低,在嵌入式设备中,可能需要几百 K 的内存数据就够了.他的处理速 ...

  5. 【转】iOS - SQLite 数据库存储

    本文目录 1.SQLite 数据库 2.iOS 自带 SQLite 的使用 3.fmdb 的使用 4.fmdb 多线程操作 5.其他 SQLite 的第三方封装库 回到顶部 1.SQLite 数据库 ...

  6. SQlite数据库框架:LitePal

    常用的数据库框架Android的发展的速度是难以置信的,Android出来哪一年我还在小学上学很,还能很清楚的记得,那年一切,但是那个时候的我怎么可能也不会想到自己将来会要去做Android.Andr ...

  7. iOS: sqlite数据库的基本操作

    介绍: sqlite3(3是版本)是本地系统中的一个小型数据库,因为它没有在数据维护和安全上做过多的操作,所以它存储处理数据时,非常简单方便,但是它是不安全和不可靠的,如果一旦误操作删除了数据,是没有 ...

  8. iOS sqlite数据库图像化查看

    问题描述:在xocde上用sqlite数据库的时候,因为没有图形化界面,有些时候很难看出自己设计的数据库是否有问题,比如我刚上手sqlite数据库设计id为自增长时,很自然的用了identify(1, ...

  9. IOS sqlite数据库增删改查

    1.简单介绍 简单封装sqlite数据库操作类 BaseDB 用于完毕对sqlite的增删改查.使用前先导入libsqlite3.0.dylib库 2.BaseDB.h // // BaseDB.h ...

随机推荐

  1. Java核心知识点学习----多线程中的阻塞队列,ArrayBlockingQueue介绍

    1.什么是阻塞队列? 所谓队列,遵循的是先进先出原则(FIFO),阻塞队列,即是数据共享时,A在写数据时,B想读同一数据,那么就将发生阻塞了. 看一下线程的四种状态,首先是新创建一个线程,然后,通过s ...

  2. easyui中tree使用simpleData的形式加载数据

    了解了zTree的使用, 发现它的simpleData是非常好用的, 由后台返回一个扁平数据, 直接在前台解析成树形菜单, 网上查了一下, easyui也可以简单实现, 不过....没看懂, 先记录一 ...

  3. SQL Server 判定时间是否在某个时间区间内

    * FROM sys.objects WHERE name=N'uF_IsRange_Date' AND [type]='FN') DROP FUNCTION uF_IsRange_Date GO S ...

  4. 問題排查:行動裝置網頁前端 UI 設計 (1)

    這是最近開始接手的一個微信公眾平台專案, 在重整後端程式碼時,因為也需要透過前端來看效果, 所以就因此在前端的部分遇到了不少問題, 畢竟這是以前沒接觸過的領域 (早年的網頁應用程式開發沒有那麼多分工) ...

  5. NC WebService接口开发流程

    一.定义类: 接口类 包定义在public下,接口类名为I开头,Service结尾 实现类 包定义在private下,实现类名以ServiceImpl结尾 VO类 若有VO类,也放在public下 U ...

  6. python 中 深拷贝和浅拷贝的理解

    在总结 python 对象和引用的时候,想到其实 对于python的深拷贝和浅拷贝也可以很好对其的进行理解. 在python中,对象的赋值的其实就是对象的引用.也就是说,当创建一个对象,然后赋给另外一 ...

  7. 云计算和大数据时代网络技术揭秘(十三)VXLAN

    Vxlan(virtual Extensible LAN)虚拟可扩展局域网,是一种Overlay方式的网络技术,采用了mac in UDP的方式 进行封装,共50字节的报头.该技术的目标是解决虚拟机在 ...

  8. 20145225《Java程序设计》 第9周学习总结

    20145225<Java程序设计> 第9周学习总结 教材学习内容总结 第十六章 整合数据库 16.1JDBC JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂 ...

  9. hibernate报错及解决方式

    1 java.sql.BatchUpdateException: ORA-01438: 值大于为此列指定的允许精度 原因:pl/sql number(n),插入的位数大于n

  10. Js之Dom学习-三种获取页面元素的方式、事件、innerText和innerHTML的异同

    一.三种获取页面元素的方式: getElementById:通过id来获取 <body> <input type="text" value="请输入一个 ...