SQLite

Sqlite

简介
  • iOS数据存数的方式
  • plist(NSArray/NSDictionary) 特点:自能存储系统自带的数据类型,自定义对象无法存储
  • preference(偏好设置)特点:本质就是一个Plist文件,也只能存储系统自带的数据类型,自定义对象无法存储
  • NSCoding 特点可以存储自定义的数据类型,但是是一次性的全数据操作
  • SQLite3 特点:存储一些大批量的数据,排序,统计操作
  • Core Data 特点:对SQLite3的封装,本质上还是SQL语句执行,
  • 钥匙串
SQLite
  • SQLite是一款轻型的嵌入式数据库,它占用的资源非常低,在嵌入式设备中,可能只需要几百K的内存就够了,它处理的速度比Mysql这款注明的数据库还快
Swift中使用SQLite
  • 创建项目,导入系统的框架sqlite3.tgb
  • 需要创建桥接文件,导入头文件sqlite3.h
  • 代码实现打开数据库
    //sqlite数据库文件的扩展名称没有一个标准,一般流行都是以sqlite,db,db3命名
     var db :COpaquePointer = nil
     func openDataBase(){
        let filename = "/Users/dingkan/Desktop" + "/demo.sqlite"
        //sqlite3_open方法用来创建打开一个数据库
        //参数一:sqlite数据库的路径
        //参数二: 一个指向SQLite3的数据的结构指针,到时候操作数据库都需要用到这个对象
        //作用:通过一个路径来创建数据库,如果路径处存在数据域,那么久打开该数据库,如果不存在就创建一个数据库
        if sqlite3_open(filename, &db) != SQLITE_OK {
            print("数据库创建失败")
        }else{
            print("数据库创建成功")
        }
    }
    
DDL语句
  • 1.创建一个数据库表
    func creatTable(){ 
        //创建sqlite语句
         let sql = "CREATE TABLE if not exists t_Student(id integer PRIMARY KEY AUTOINCREMENT,name text not NULL, age integer default 18, source integer)"
        //参数一: 一个打开的数据库
        //参数二: sql语句
        //参数三:回调结果,执行完毕后回调的函数,如果不需要可以传nil
        //参数4:参数三的第一个参数,可以通过这个参数传值给回调的函数,如果不需要就传nil
        //参数5:错误信息
        if sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK {
            print("列表创建成功")
        }else{
            print("列表创建失败")
        }
    
  • 2.删除数据库表
        //删除表格
    func dropTable(){
        let sql = "drop table if exists t_Student"
        if exec(sql){
            print("删除成功")
        }else{
            print("删除失败")
        }
    }
    
  • 3.修改数据库表
       func alterTable(){
        let sql = "alter table t_Student add column name text"
        if exec(sql){
            print("添加成功")
        }else{
            print("添加失败")
        }
    }
    //抽取
        func exec(sql: String) ->Bool{
        return sqlite3_exec(db, sql, nil, nil, nil) == SQLITE_OK
    }
    
DML语句
  • 1.插入数据
    -sqlit语句格式:insert into 表名(字段1,字段2...) values(字段1的值,字段2的值...);
    -利用代码来插入数据

        func insert()->Bool{
        let sql = "insert into t_Student(name, age, source) values('\(name)' , \(age),\(source))"
        return Tool.shareInstance.exec(sql)
    }
    
  • 2.更新数据

    • sqlite语句格式:update 表名 set 字段1 = 字段1的值, 字段2 = 字段2的值...;
    • 利用代码来实现更新数据
        class func update(stu:DKStudent)->Bool{
        let sql = "update t_Student set name='\(stu.name)',age = \(stu.age), source = \(stu.source)"
        return Tool.shareInstance.exec(sql)
    }
    
  • 3.删除数据

    • sqlite语句格式: delete from 表名 Where 字段1 = 字段1的值...;
    • 利用代码来实现删除数据
        func delete()->Bool{
        let sql = "delete from t_Student where name = '\(name)'"
        return Tool.shareInstance.exec(sql)
    }
    
  • Insert绑定参数

  • 准备语句(prepared tatement)对象,准备语句对象,代表了一个简单的SQL语句对象的实例,这个对象通常被称作准备语句获取编译好的SQL语句

  • 操作过程

    • 1.创建准备语句对象,如果执行成功,则返回SQLITE_OK,否则返回一个错误码

//1.固定写法
let sql = "insert into t_Student(name, age, source) values(?, ?, ?)"
//2.创建准备语句
let db = Tool.shareInstance.db
参数一: 数据库
参数二: sql语句
参数三: 代表从sql字符串中取出的长度, -1代表自动计算
参数四: 代表准备语句地址
参数五: 按照参数三从参数二中取出字符串剩下的字符串
//创建一个空的准备语句,获取返回的结果
var stmt : COpaquePointer = nil
if sqlite3_prepare_v2(db, sql, -1, &stmt, nil) != SQLITE_OK{
print("编译失败")
return
}


    - 2.绑定参数
    ```
//  绑定参数
//参数一: 准备语句
//参数二: 绑定的参数索引(从1开始)
//参数三: 绑定的参数的内容
//参数四: 绑定参数的长度 -1代表自动计算
//参数五: 参数的处理方式
// #define SQLITE_STATIC      会对字符串做一个copy,SQLite选择合适的机会释放
 //#define SQLITE_TRANSIENT    会当做全局静态变量,不会对字符串做任何处理,如果字符串被释放,保存到数据库的内容可能不正确
 //swift中没有宏的概念,所以需要替换
let SQLITE_TRANSIENT = unsafeBitCast(-1, sqlite3_destructor_type.self)
sqlite3_bind_text(stmt, 1,"aa", -1, SQLITE_TRANSIENT)
sqlite3_bind_int(stmt, 2, 13)
sqlite3_bind_double(stmt, 3, 80.0)
    ```
    
    - 3.执行sql
    ```
    //对于DML语句,如果执行成功,则返回SQLITE_DONE,
    //对于DQL语句,通过多次执行获取结果集,继续执行的条件是SQLITE_ROW
    if sqlite3_step(stmt) != SQLITE_DONE{
        print("执行失败")
        return
        }
    ```
    - 4.重置语句
    ```
    sqlite3_reset(stmt)//使用sqlite3_reset()重置这个语句,让后回到上一步,绑定参数,这个过程可能做0次,也可能左多次
    ```
    - 5.销毁对象,防止内存泄露
    ```
    sqlite3_finalize()
    ```
    
#####Transaction事务
- 事务是并发控制的单位,是用户定义的一个操作序列,这个操作要么做,要么都不做,是一个不可分割的工作单位,通过事务,可以将逻辑相关的一些操作绑定在一起,保证数据的完整性
-使用事务来优化
- 大批量数据插入的优化
- 第一层优化: 使用`准备语句`
- 第二层优化: 无论是sqlite3_exec,还是sqlite3_step,都会在内容自动`开启事务`,自动`提交事务`,一旦自动开启,自动提交,就会非常的耗时,
- 解决方案: 只要我们手动开启,和手动提交,那么系统就不会来自动执行,

######DQL语句
- 代码实现DQL语句的方式
- 方式一: 利用sqlite3_exec来实现,作用: 可以通过回调来获取结果,步骤相对简单,结果数据类型没有特定类型(id)
    ```
        func queryALl(){
        //方式一: 通过sqlite_exec来查询
        //sql语句
        let sql = "select * from t_Student"
        let db = Tool.shareInstance.db
        //参数一:可以打开的数据库
        //参数二:需要执行的SQL语句
        //参数三 查询结果回调
            //参数1: 参数4的值
            //参数2: 列的个数
            //参数3: 结果值的数组
            //参数4: 所有列的名称数组
            //返回值为0 表示继续查询,返回值非0 表示终止查询
        //参数四:回调函数的第一个参数
        //参数五:错误信息
        sqlite3_exec(db, sql, { (firsPara, columnCount, values, columnNames) -> Int32 in
        //将UnsafeMutablePointer转换成int类型
            let count = Int(columnCount)
            for i in 0..(sqlite3_column_text(stmt, i)) 
                    let valueStr = String(CString: value, encoding: NSUTF8StringEncoding)
                    print(valueStr)
                }
            }
        }
        // 4. 重置(可以省略)
        // 5. 释放资源
        sqlite3_finalize(stmt)
    }
    ```

你可能感兴趣的:(SQLite)