SQLite.swift 是一个使用纯 Swift 语言封装 SQLite3 的操作框架。
特性:
示范代码:
import Foundation /** 1. 打开数据库 2. 如果没有数据表,需要首先创表 3. 数据操作 */ class SQLite { var db: COpaquePointer = nil /// 打开数据库 /// /// :param: dbname 数据库名称 /// /// :returns: 是否打开成功 func openDatabase(dbname: String) -> Bool { // UnsafePointer<Int8> UnsafePointer<CChar> // 对应C语言中的 char* // filename 必须是完整的路径名 let path = dbname.documentPath() println(path) // sqlite3_open 如果如果数据库不存在,会新建数据库文件 // 如果数据库文件已经存在,就直接打开,返回句柄,不会对数据有任何影响 if sqlite3_open(path, &db) == SQLITE_OK { println("打开数据库成功") // 本质上只需要运行一次就可以了 if createTable() { println("创表成功") // TODO: 测试查询数据 let sql = "SELECT id, DepartmentNo, Name FROM T_Department;" recordSet(sql) } else { println("创表失败") } } else { println("打开数据库失败") } return false } /// 创建数据表,将系统需要的数据表,一次性创建 private func createTable() -> Bool { // 准备所有数据表的 SQL // 1> 每一个 SQL 完成后都有一个 ; // 2> 将所有创表 SQL 写在一起,每一个换行添加一个 \n let sql = "CREATE TABLE \n" + "IF NOT EXISTS T_Department (\n" + "id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,\n" + "DepartmentNo CHAR(10) NOT NULL DEFAULT '',\n" + "Name CHAR(50) NOT NULL DEFAULT '' \n" + "); \n" + "CREATE TABLE IF NOT EXISTS T_Employee ( \n" + "'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, \n" + "'name' TEXT NOT NULL, \n" + "'age' INTEGER NOT NULL, \n" + "'department_id' INTEGER, \n" + "CONSTRAINT 'FK_DEP_ID' FOREIGN KEY ('department_id') REFERENCES 'T_Department' ('id') \n" + ");" return execSQL(sql) } /// 执行没有返回值的 SQL 语句 /// /// :param: sql SQL 字符串 /// /// :returns: 是否成功 func execSQL(sql: String) -> Bool { /** 1. 数据库指针 2. SQL 字符串的 C 语言格式 3. 回调,执行完成 SQL 指令之后的函数回调,通常都是 nil 4. 回调的第一个参数的指针 5. 错误信息,通常也传入 nil */ return sqlite3_exec(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, nil, nil, nil) == SQLITE_OK } /// 执行 SQL 返回一个结果集(对象数组) /// /// :param: sql SQL 字符串 func recordSet(sql: String) { // 1. 准备语句 var stmt: COpaquePointer = nil /** 1. 数据库句柄 2. SQL 的 C 语言的字符串 3. SQL 的 C 语言的字符串长度 strlen,-1 会自动计算 4. stmt 的指针 5. 通常传入 nil */ if sqlite3_prepare_v2(db, sql.cStringUsingEncoding(NSUTF8StringEncoding)!, -1, &stmt, nil) == SQLITE_OK { // 单步获取SQL执行的结果 -> sqlite3_setup 对应一条记录 while sqlite3_step(stmt) == SQLITE_ROW { // 获取每一条记录的数据 recordData(stmt) } } } /// 获取每一条数据的记录 /// /// :param: stmt prepared_statement 对象 func recordData(stmt: COpaquePointer) { // 获取到记录 var count = sqlite3_column_count(stmt) println("获取到记录,共有多少列 \(count)") // 遍历每一列的数据 for i in 0..<count { let type = sqlite3_column_type(stmt, i) // 根据字段的类型,提取对应列的值 switch type { case SQLITE_INTEGER: println("整数 \(sqlite3_column_int64(stmt, i))") case SQLITE_FLOAT: println("小树 \(sqlite3_column_double(stmt, i))") case SQLITE_NULL: println("空 \(NSNull())") case SQLITE_TEXT: let chars = UnsafePointer<CChar>(sqlite3_column_text(stmt, i)) let str = String(CString: chars, encoding: NSUTF8StringEncoding)! println("字符串 \(str)") case let type: println("不支持的类型 \(type)") } } } }