1.什么是FMDB:
- FMDB是iOS平台的SQLite数据库框架
- FMDB以OC的方式封装了SQLite的C语言API
FMDB的优点:
- 使用起来更加面向对象,省去了很多麻烦、冗余的C语言代码提供了多线程安全的数据库操作方法,有效地防止数据混乱
FMDB的github地址:
2.核心类
FMDB有三个主要的类
- FMDatabase
- 一个FMDatabase对象就代表一个单独的SQLite数据库用来执行SQL语句
-
FMResultSet
- 使用FMDatabase执行查询后的结果集
-
FMDatabaseQueue
- 用于在多线程中执行多个查询或更新,它是线程安全的
3.通过指定SQLite数据库文件路径来创建FMDatabase对象
FMDatabase *db = [FMDatabase databaseWithPath:path];
if(![db open])
{
NSLog(@"数据库打开失败!");
}
文件路径有三种情况:
- 具体文件路径
- 如果不存在会自动创建
- 空字符串@""
- 会在临时目录创建一个空的数据库
- 当FMDatabase连接关闭时,数据库文件也被删除
- nil
- 会创建一个内存中临时数据库,当FMDatabase连接关闭时,数据库会被销毁
4.执行更新/执行查询
################## 更新方法 ################
在FMDB中,除查询以外的所有操作,都称为“更新”,create、drop、insert、update、delete等使用executeUpdate:方法执行更新
- (BOOL)executeUpdate:(NSString*)sql,...
- (BOOL)executeUpdateWithFormat:(NSString*)format,...
- (BOOL)executeUpdate:(NSString*)sql withArgumentsInArray:(NSArray *)arguments
n示例
[db executeUpdate:@"UPDATE t_student SET age = ?WHERE name = ?;", @20, @"Jack"]
-------------------------------------------------------------
################################## 查询方法 ##################################
(FMResultSet *)executeQuery:(NSString*)sql,...
(FMResultSet *)executeQueryWithFormat:(NSString *)format,...
(FMResultSet *)executeQuery:(NSString *)sql withArgumentsInArray:(NSArray *)arguments
示例
//查询数据
FMResultSet *rs = [db executeQuery:@"SELECT * FROM t_student"];
//遍历结果集
while([rs next])
{
NSString *name = [rs stringForColumn:@"name"];
int age = [rs intForColumn:@"age"];
double score = [rs doubleForColumn:@"score"];
}
5.FMDatabaseQueue
FMDatabase这个类是线程不安全的,如果在多个线程中同时使用一个FMDatabase实例,会造成数据混乱等问题为了保证线程安全,FMDB提供方便快捷的FMDatabaseQueue类
FMDatabaseQueue的创建:
FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
使用事务
[queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jack"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Rose"];
[db executeUpdate:@"INSERT INTO t_student(name) VALUES (?)", @"Jim"];
FMResultSet *rs = [db executeQuery:@"select * from t_student"];
while ([rs next])
{
//执行操作
}
}];
事务回滚
*rollback = YES;
01-FMDB基本使用
桥接文件
// Sqlite+Bridge.h
// 01-FMDB基本使用
// Created by ming on 16/04/16.
// Copyright © 2016年 ming. All rights reserved.
#import "FMDB.h"
SQLiteManager
// SQLiteManager.swift
// 01-FMDB基本使用
// Created by ming on 16/04/16.
// Copyright © 2016年 ming. All rights reserved.
import UIKit
class SQLiteManager: NSObject {
/// 单例
static let shareInstance: SQLiteManager = SQLiteManager()
override init() {
super.init()
openDB("demo.sqlite")
}
var db: FMDatabase?
func openDB(name: String)
{
// 1.拼接路径
let path = name.documentDir()
// 2.创建数据库对象
db = FMDatabase(path: path)
// 3.打开数据库
// open()特点: 如果数据库文件不存在就创建一个新的, 如果存在就直接打开
if !db!.open()
{
print("打开数据库失败")
return
}
// 4.创建表
if !createTable()
{
print("创建数据库失败")
return
}
}
/**
创建表
*/
func createTable() ->Bool
{
// 1.编写SQL语句
let sql = "CREATE TABLE IF NOT EXISTS T_Person( \n" +
"id INTEGER PRIMARY KEY AUTOINCREMENT, \n" +
"name TEXT, \n" +
"age INTEGER \n" +
");"
// 2.执行SQL语句
// 注意: 在FMDB中, 除了查询以外的操作都称之为更新
return db!.executeUpdate(sql, withArgumentsInArray: nil)
}
}
ViewController
// ViewController.swift
// 01-FMDB基本使用
// Created by ming on 16/04/16.
// Copyright © 2016年 ming. All rights reserved.
import UIKit
class ViewController: UIViewController {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("abc".documentDir())
// SQLiteManager.shareInstance.openDB("demo.sqlite")
/// DML
let sql = "INSERT INTO T_Person \n" +
"(name, age) \n" +
"VALUES \n" +
"(?, ?);"
// SQLiteManager.shareInstance.db?.executeUpdate(sql, withArgumentsInArray: nil)
SQLiteManager.shareInstance.db?.executeUpdate(sql, withArgumentsInArray: ["ls", 88])
/// 查询语句
let sql2 = "SELECT id, name, age FROM T_Person;"
// 1.查询数据库
let result = SQLiteManager.shareInstance.db!.executeQuery(sql2, withArgumentsInArray: nil)
// 2.从结果集中取出数据
while result.next()
{
let id = result.intForColumn("id")
let name = result.stringForColumn("name")
let age = result.intForColumn("age")
print("\(id), \(name), \(age)")
}
}
}
02-FMDBQueue基本使用
import UIKit
class SQLiteManager: NSObject {
/// 单例
static let shareInstance: SQLiteManager = SQLiteManager()
override init() {
super.init()
openDB("demo.sqlite")
}
var dbQueue: FMDatabaseQueue?
func openDB(name: String) {
// 1.拼接路径
let path = name.documentDir()
// 2.创建数据库对象
dbQueue = FMDatabaseQueue(path: path)
// 3.创建表
createTable()
}
/**
创建表
*/
func createTable() {
// 1.编写SQL语句
let sql = "CREATE TABLE IF NOT EXISTS T_Person( " +
"id INTEGER PRIMARY KEY AUTOINCREMENT, " +
"name TEXT," +
"age INTEGER " +
");"
// 2.执行SQL语句
dbQueue?.inDatabase({ (db) -> Void in
db.executeUpdate(sql, withArgumentsInArray: nil)
})
}
}
import UIKit
class ViewController: UIViewController {
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
print("abc".documentDir())
// SQLiteManager.shareInstance.openDB("demo.sqlite")
/// DML
let sql = "INSERT INTO T_Person " +
"(name, age) " +
"VALUES " +
"(?, ?);"
// 只要使用inTransaction, 那么在inTransaction闭包中的所有代码都是在事务中执行的
SQLiteManager.shareInstance.dbQueue!.inTransaction { (db, rollback) -> Void in
for i in 0..<10
{
db.executeUpdate(sql, withArgumentsInArray: ["zs", 30])
// if i == 5
// {
// // OC中的写法: *rollback = YES;
// // Swift2.x中的写法: rollback.memory = true
// // Swift3.0中的写法: rollback?.pointee = true
// rollback.memory = true
// }
}
}
}