FMDB
框架使用(作者离职,求一份工作)
- 将 fmdb 文件夹拖入项目
- 建立桥接文件
- 将 Swift extensions 拖入项目
- 添加 libsqlite3.tdb
FMDB 架构图
代码演练之创建数据库到对数据的增删改查
import Foundation
/// 数据库名称
private let dbname = "my.db"
class SQLiteManager {
/// 单例 - 全局访问点
static let sharedManager = SQLiteManager()
/// 全局数据库操作队列 对于常量而言,有一次设置数值的机会
let queue: FMDatabaseQueue
// 使用 private 可以保证外界统一通过 sharedManager 访问
private init() {
print("基本准备工作")
var path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
path = (path as NSString).stringByAppendingPathComponent(dbname)
print(path)
// 1. 打开数据库
/**
参数:数据库的全路径
返回:数据库操作队列,全局数据库的访问入口
特点:如果数据库存在,打开数据库,建立队列
如果数据库不存在,新建数据库,建立队列
*/
queue = FMDatabaseQueue(path: path)
// 2. 创建数据表
createTables()
}
//MARK: - 增加数据
/// 使用`预编译` SQL 插入数据
private func insertPerson4(name: String,age:NSInteger,height:Double) {
// 1. 准备 SQL
/**
特点:
1> 使用 ? 作为参数的占位符号
2> 提前编译 SQL,确认语法正确
3> 在真正执行 SQL 的时候,使用参数,替换 `?`
4> 预编译 SQL 中的字符串,不需要使用单引号 '
更加安全,可以留存用户输入的所有内容!推荐使用!
*/
let sql = "INSERT INTO T_Person (name, age, height) VALUES (?, ?, ?);"
// 2. 执行 sql
queue.inDatabase { (db) -> Void in
// 执行单条语句更安全
do {
try db.executeUpdate(sql, name, age, height)
} catch {
print("数据插入失败 \\(error)")
}
}
}
// MARK: - 删除数据
private func deletePerson(id: Int) {
let sql = "DELETE FROM T_Person WHERE id = :id;"
queue.inDatabase { (db) -> Void in
if db.executeUpdate(sql, withParameterDictionary: ["id": id]) {
print("删除成功 删除的数据行数为 \\(db.changes())")
} else {
print("删除失败")
}
}
}
// MARK: - 更新数据
private func updatePerson(dict: [String: AnyObject]) {
// 如果条件不符合,会正常执行,不会报错
var sql = "UPDATE T_Person set name = :name, age = :age, height = :height \\n"
sql += "WHERE id = :id;"
queue.inDatabase { (db) -> Void in
if db.executeUpdate(sql, withParameterDictionary: dict) {
print("更新成功 更新的数据行数为 \\(db.changes())")
} else {
print("更新失败")
}
}
}
//MARK: - 查询数据
/// 执行 SQL 返回结果集合[字典数组]
///
/// - parameter sql: 要执行的 SQL
///
/// - returns: 返回查询结果,如果 SQL 语法错误,返回 nil
func execRecordSet(sql: String) -> [[String: AnyObject]]? {
// `定义`字典数组,var 的可选项的默认值是 nil
var recordSet: [[String: AnyObject]]?
queue.inDatabase { (db) -> Void in
guard let rs = try? db.executeQuery(sql) else {
print("SQL 语句错误")
return
}
// 实例化字典
recordSet = [[String: AnyObject]]()
while rs.next() {
// 1. 知道查询结果的列数
let colCount = rs.columnCount()
// 2. 定义一行的字典
var row = [String: AnyObject]()
for col in 0..<colCount {
// 1> 获得列名
let name = rs.columnNameForIndex(col)
// 2> 获得值
let value = rs.objectForColumnIndex(col)
// 3> 设置字典
row[name] = value
}
// 添加到数组
recordSet!.append(row)
}
}
// 返回查询结果
return recordSet
}
/// 建立数据表
private func createTables() {
// 1. 准备 sql
let path = NSBundle.mainBundle().pathForResource("db.sql", ofType: nil)!
let sql = try! String(contentsOfFile: path)
print(sql)
// 2. 执行 sql,串行队列同步执行,保证数据安全
queue.inDatabase { (db) -> Void in
// 执行 `单条` SQL - 不适合创建数据表,因为一次只能执行一条
// 如果有多个表,会很麻烦
// do {
// try db.executeUpdate(sql)
// } catch {
// print("创建数据表失败 \\(error)")
// }
// 执行`多条` SQL - 仅适合用于创建数据表,可以一次创建多个表
if db.executeStatements(sql) {
print("创表成功")
} else {
print("创表失败")
}
// 使用 FMDB 时,一定注意不要嵌套使用,否则死锁!
// self.queue.inDatabase({ (db) -> Void in
//
// })
}
print("come here")
}
}
sql常用语句
创建表
CREATE TABLE IF NOT EXISTS "T_Person" (
"id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"name" TEXT,
"age" INTEGER,
"heigth" REAL
)
//下边是sqllite编译器里边的语句
/*简单约束*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER
);
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT UNIQUE,
age INTEGER
);
/*添加主键*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
age INTEGER,
score REAL
);
/*添加主键*/
CREATE TABLE IF NOT EXISTS t_student
(
id INTEGER,
name TEXT,
age INTEGER,
score REAL,
PRIMARY KEY(id)
);
查询
/*分页*/
SELECT * FROM t_student
ORDER BY id ASC LIMIT 30, 10;
/*排序*/
SELECT * FROM t_student
WHERE score > 50
ORDER BY age DESC;
SELECT * FROM t_student
WHERE score < 50
ORDER BY age ASC , score DESC;
/*计量*/
SELECT COUNT(*)
FROM t_student
WHERE age > 50;
/*别名*/
SELECT name as myName, age as myAge, score as myScore
FROM t_student;
SELECT name myName, age myAge, score myScore
FROM t_student;
SELECT s.name myName, s.age myAge, s.score myScore
FROM t_student s
WHERE s.age > 50;
/*查询*/
SELECT name, age, score FROM t_student;
SELECT * FROM t_student;
修改
UPDATE t_student
SET name = 'MM'
WHERE age = 10;
UPDATE t_student
SET name = 'WW'
WHERE age is 7;
UPDATE t_student
SET name = 'XXOO'
WHERE age < 20;
UPDATE t_student
SET name = 'NNMM'
WHERE age < 50 and score > 10;
/*更新记录的name*/
UPDATE t_student SET name = 'zhangsan';
删除
DELETE FROM t_student;
DELETE FROM t_student WHERE age < 50;
插入
INSERT INTO t_student
(age, score, name)
VALUES
('28', 100, 'zhangsan');
INSERT INTO t_student
(name, age)
VALUES
('lisi', '28');
INSERT INTO t_student
(score)
VALUES
(100);
删除表
/*删除表*/
DROP TABLE IF EXISTS t_student;