Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用

文章目录

        • 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 库

Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第1张图片
选择最新版

2.5 通过建立一个Objective-C 文件来获得桥接头文件

我们要做的就是调用引入的 libsqlite3.tbd 里面的接口。

因为它是用 C 语言写的,所以我们需要一个桥接头文件(bridging header)。

Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第2张图片

Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第3张图片

2.6 删除 Objective-C 文件
2.7 在桥接文件中引入 SQLite 的头文件

Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第4张图片

这样我们就可以调用引用进来的 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)
    }
    
    
    /**
            执行数据库语句
            1. 创建 create
            2. 插入 insert
            3. 更新 update
            4. 删除 delete
     */
    func execNoneQuerySQL(sql:String)->Bool{
        
        var errMsg:UnsafeMutablePointer<Int8>? = nil   //错误信息的指针(不安全、可修改)
        let cSql = sql.cString(using: String.Encoding.utf8)!  //给sql语句进行编码
        
        /**
            参数说明:
                1. 已打开的数据库句柄
                2. 执行的sql语句
                3. 回调函数
                4. 自定义指针,会传递到回调函数内
                5. 错误信息指针
         */
        //执行成功
        if sqlite3_exec(database, cSql, nil, nil, &errMsg) == SQLITE_OK {
            return true
        }
        
        //执行不成功
        let msg = String.init(cString: errMsg!)
        print(msg)
        return false
        
    }
    
    /**
            执行数据库语句
                1. 查询
     */
    func execQuerySQL(sql:String)->[[String:AnyObject]]?{
        
        let cSql = sql.cString(using: String.Encoding.utf8)!  //对sql语句进行utf8编码
        var statement:OpaquePointer? = nil  //语句的指针
        
        /**
                参数说明:
                    1. 已打开的数据库句柄
                    2. 执行的sql语句
                    3. 以字节为单位的sql语句长度,-1表示自动计算
                    4. 语句句柄,据此获取查询结果,需要调用 sqlite3_finalize 释放
                    5. 未使用的指针地址,通常传入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('张三','[email protected]');"
        let stu1 = "INSERT INTO student(name,phone) VALUES('李四','[email protected]');"
        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 界面

Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第5张图片

6. 效果

  • 界面(显示 id = 1 的所有信息)
    Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第6张图片
  • 点击按钮,控制台信息
    Swift — UIKit 之(10)—— 持久层|SQLite 的基本使用_第7张图片

你可能感兴趣的:(iOS,Swift,UIKit)