文章目录
- 0. 本篇重点
- 1. SQLite 介绍
- 2. 引入 SQLite 库
- 2.1 新建 Single View App
- 2.2 新建一个纯代码文件 SQLiteManager.swift
- 2.3 新建一个纯代码文件 Test.swift
- 2.4 添加 SQLite 库
- 2.5 通过建立一个Objective-C 文件来获得桥接头文件
- 2.6 删除 Objective-C 文件
- 2.7 在桥接文件中引入 SQLite 的头文件
- 3. 编写 SQLiteManger.swift
- 4. 编写 Test.swift
- 5. 设计 Main.storyboard 界面
- 6. 效果
0. 本篇重点
本篇主要整理一下 Swift 中如何使用 SQLite 这一轻量级数据库。
- SQLite 接口的引入
- SQLite 的基本操作(开启关闭和CRUD)
1. SQLite 介绍
百度百科:https://baike.baidu.com/item/SQLite
官网:https://www.sqlite.org/index.html
2. 引入 SQLite 库
2.1 新建 Single View App
2.2 新建一个纯代码文件 SQLiteManager.swift
2.3 新建一个纯代码文件 Test.swift
2.4 添加 SQLite 库
选择最新版
2.5 通过建立一个Objective-C 文件来获得桥接头文件
我们要做的就是调用引入的 libsqlite3.tbd 里面的接口。
因为它是用 C 语言写的,所以我们需要一个桥接头文件(bridging header)。
2.6 删除 Objective-C 文件
2.7 在桥接文件中引入 SQLite 的头文件
这样我们就可以调用引用进来的 libsqlite3.tbd 里面的接口了。
3. 编写 SQLiteManger.swift
//
// SQLiteManager.swift
// S0902
//
// Created by Hedon - on 2020/4/15.
// Copyright © 2020 Hedon -. All rights reserved.
//
import Foundation
class SQLiteManager:NSObject
{
private var dbPath:String! //数据库所存储的文件所在路径
private var database:OpaquePointer?=nil //数据库,是一个指针,指向一个结构体
//共享一个实例化对象 —————— 单例变量
static var shareInstance:SQLiteManager{
return SQLiteManager()
}
override init() {
let dirpath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
dbPath = dirpath.appendingPathComponent("app.sqlite").path
}
//打开数据库
func openDB() -> Bool {
let result = sqlite3_open(dbPath, &database)
if result != SQLITE_OK{
print("打开数据库失败")
return false
}
return true
}
//关闭数据库
func closeDB(){
sqlite3_close(database)
}
func execNoneQuerySQL(sql:String)->Bool{
var errMsg:UnsafeMutablePointer<Int8>? = nil //错误信息的指针(不安全、可修改)
let cSql = sql.cString(using: String.Encoding.utf8)! //给sql语句进行编码
//执行成功
if sqlite3_exec(database, cSql, nil, nil, &errMsg) == SQLITE_OK {
return true
}
//执行不成功
let msg = String.init(cString: errMsg!)
print(msg)
return false
}
func execQuerySQL(sql:String)->[[String:AnyObject]]?{
let cSql = sql.cString(using: String.Encoding.utf8)! //对sql语句进行utf8编码
var statement:OpaquePointer? = nil //语句的指针
//执行不成功
if sqlite3_prepare_v2(database, cSql, -1, &statement, nil) != SQLITE_OK{
sqlite3_finalize(statement)
print("执行 \(sql) 错误")
let errmsg = sqlite3_errmsg(database)
if errmsg != nil{
print(errmsg!)
}
return nil
}
//成功:需要从 statement 里面取数据,定义 rows 变量来接收数据
var rows = [[String:AnyObject]]()
//每次取 1 行
while sqlite3_step(statement) == SQLITE_ROW{
rows.append(record(stmt: statement!))
}
//最后释放空间
sqlite3_finalize(statement)
//返回结果
return rows
}
//读一行记录一行
private func record(stmt:OpaquePointer)->[String:AnyObject]{
var row = [String:AnyObject]()
//遍历所有列,获取每一列的信息
for col in 0..<sqlite3_column_count(stmt){
let cName = sqlite3_column_name(stmt, col) //获取列名
let name = String(cString: cName!,encoding: String.Encoding.utf8)
var value:AnyObject?
switch sqlite3_column_type(stmt, col) {
case SQLITE_FLOAT:
value = sqlite3_column_double(stmt, col) as AnyObject
case SQLITE_INTEGER:
value = Int(sqlite3_column_int(stmt, col)) as AnyObject
case SQLITE_TEXT:
let cText = sqlite3_column_text(stmt, col)
value = String.init(cString: cText!) as AnyObject
case SQLITE_NULL:
value = NSNull()
default:
print("不支持的数据类型")
}
row[name!] = value ?? NSNull()
}
return row
}
}
4. 编写 Test.swift
//
// Test.swift
// S0902
//
// Created by Hedon - on 2020/4/15.
// Copyright © 2020 Hedon -. All rights reserved.
//
import Foundation
class Test
{
static func initDB()
{
//引用SQLiteManager的单例对象
let sqlite = SQLiteManager.shareInstance
//没打开则返回
if !sqlite.openDB()
{
return
}
//创建表
let createSql = "CREATE TABLE IF NOT EXISTS student('id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT," + "'name' TEXT, 'phone' TEXT);"
if !sqlite.execNoneQuerySQL(sql: createSql) //如果不成功,则关闭数据库并返回。
{
sqlite.closeDB()
return
}
//清除表
let cleanAllStu = "DELETe FROM student;"
if !sqlite.execNoneQuerySQL(sql: cleanAllStu)
{
sqlite.closeDB()
return
}
//重置表
let resetStu = "DELETe FROM sqlite_sequence WHERe name = 'student';"
if !sqlite.execNoneQuerySQL(sql: resetStu)
{
sqlite.closeDB()
return
}
//插入数据
let stu0 = "INSERT INTO student(name,phone) VALUES('张三','zhangsan@whu.edu.cn');"
let stu1 = "INSERT INTO student(name,phone) VALUES('李四','lisi@whu.edu.cn');"
if !sqlite.execNoneQuerySQL(sql: stu0)
{
sqlite.closeDB()
return
}
if !sqlite.execNoneQuerySQL(sql: stu1)
{
sqlite.closeDB()
return
}
//关闭数据库
sqlite.closeDB()
}
static func GetStudent()
{
//获取SQLiteManager的单例对象
let sqlite = SQLiteManager.shareInstance
//打开数据库
if !sqlite.openDB(){return}
//查询所有
let queryResult = sqlite.execQuerySQL(sql: "SELECt * FROM student;")
print(queryResult!)
for row in queryResult!
{
print(row["name"]!)
}
//关闭数据库
sqlite.closeDB()
}
static func GetID1()->[AnyObject]
{
var info:[AnyObject] = []
//获取SQLiteManager的单例对象
let sqlite = SQLiteManager.shareInstance
//打开数据库
if !sqlite.openDB(){return info}
//查询所有
let queryResult = sqlite.execQuerySQL(sql: "SELECt * FROM student WHERe id=1;")
print(queryResult!)
for row in queryResult!
{
info.append(row["id"]!)
info.append(row["name"]!)
info.append(row["phone"]!)
}
//关闭数据库
sqlite.closeDB()
return info
}
}
5. 设计 Main.storyboard 界面
6. 效果
- 界面(显示 id = 1 的所有信息)
- 点击按钮,控制台信息