Swift 中使用 sqlite
准备工作
- 添加
libsqlite3.tbd
- 创建
sqlite-Bridge.h
- 选择
项目
-TARGETS
-Build Settings
,搜索Bridg
- 在
Objective-C Bridging Header
中输入项目名/sqlite-Bridge.h
- 如果之前设置过桥接文件,可以直接使用
编译测试
sqliteManager
与网络接口的独立类似,数据库的底层操作,也应该有一个独立的对象单独负责
sqliteManager
单例
/// sqlite 管理器
class sqliteManager {
/// 单例
static let sharedManager = sqliteManager()
}
数据库访问操作需求
建立&打开数据库
/// 数据库句柄
private var db: COpaquePointer = nil
/// 打开数据库
///
/// - parameter dbname: 数据库文件名
func openDB(dbname: String) {
let path = (NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory,NSSearchPathDomainMask.UserDomainMask,true).last! as NSString).stringByAppendingPathComponent(dbname)
print(path)
if sqlite3_open(path,&db) != sqlITE_OK {
print("打开数据库失败")
return
}
print("打开数据库成功")
}
代码小结
打开数据库
func application(application: UIApplication,didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
sqliteManager.sharedManager.openDB("my.db")
return true
}
代码小结
sqlite
数据库是直接保存在沙盒中的一个文件,只有当前应用程序可以使用- 在移动端开发时,数据库通常是以
持久式
连接方式使用的 - 所谓
持久式连接
指的是只做一次打开数据库
的操作,永远不做关闭
数据库的操作,从而可以提高数据库的访问效率
创建数据表
注意:创表操作本质上是通过执行
sql
语句实现的
/// 执行 sql
///
/// - parameter sql: sql
///
/// - returns: 是否成功
func execsql(sql: String) -> Bool {
/** 参数 1. 数据库句柄 2. 要执行的 sql 语句 3. 执行完成后的回调,通常为 nil 4. 回调函数第一个参数的地址,通常为 nil 5. 错误信息地址,通常为 nil */
return sqlite3_exec(db,sql,nil,nil) == sqlITE_OK
}
- 创建数据表
/// 创建数据表
///
/// - returns: 是否成功
private func createTable() -> Bool {
let sql = "CREATE TABLE IF NOT EXISTS T_Person \n" +
"('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,\n" +
"'name' TEXT,\n" +
"'age' INTEGER);"
print(sql)
return execsql(sql)
}
- 调整
openDB
函数
if createTable() {
print("创表成功")
} else {
print("创表失败")
db = nil
}
代码小结
- 创表
sql
可以从Navicat
中粘贴,然后做一些处理
数据模型
- 建立
Person
模型
class Person: NSObject {
/// id
var id: Int = 0
/// 姓名
var name: String?
/// 年龄
var age: Int = 0
/// 使用字典创建 Person 对象
init(dict: [String: AnyObject]) {
super.init()
setValuesForKeysWithDictionary(dict)
}
}
- 新增数据
/// 将当前对象插入到数据库
///
/// - returns: 是否成功
func insertPerson() -> Bool {
assert(name != nil,"姓名不能为空")
let sql = "INSERT INTO T_Person (name,age) VALUES ('\(name!)',\(age));"
return sqliteManager.sharedManager.execsql(sql)
}
/// 测试插入数据
func demoInsert() {
print(Person(dict: ["name": "zhangsan","age": 18]).insertPerson())
}
- 更新记录
/// 更新当前对象在数据库中的记录
///
/// - returns: 是否成功
func updatePerson() -> Bool {
assert(name != nil,"姓名不能为空")
assert(id > 0,"ID 不正确")
let sql = "UPDATE T_Person SET name = '\(name!)',age = \(age) WHERE id = \(id);"
return sqliteManager.sharedManager.execsql(sql)
}
/// 测试更新记录
func demoUpdate() {
print(Person(dict: ["id": 1,"name": "lisi","age": 20]).updatePerson())
}
- 删除数据
/// 删除当前对象在数据库中的记录
///
/// - returns: 是否成功
func deletePerson() -> Bool {
assert(id > 0,"ID 不正确")
let sql = "DELETE FROM T_Person WHERE ID = \(id);"
return sqliteManager.sharedManager.execsql(sql)
}
/// 测试删除记录
func demoDelete() {
print(Person(dict: ["id": 1,"age": 20]).deletePerson())
}
- 测试批量插入
/// 测试批量插入数据
func insertManyPerson() {
print("开始")
let start = CFAbsoluteTimeGetCurrent()
for i in 0..<100000 {
Person(dict: ["name": "lisi-\(i)","age": Int(arc4random_uniform(10)) + 20]).insertPerson()
}
print(CFAbsoluteTimeGetCurrent() - start)
}
非常耗时,大概需要1分钟左右