iOS中SQLite知识点总结2

数据库(SQLite)

01-多表查询

  • 格式:select 字段1,字段2,... from 表名1,表名2;
  • 别名:select 别名1.字段1 as 字段别名1,别名2.字段2 as 字段别名2,... from 表名1 as 别名1,表名2 as 别名2;
  • 能够给表或字段单独起别名,as可省略
  • 表链接查询:select 字段1,字段2,... from 表名1,表名2 where 表名1.id = 表名2.id;
  • 外键:
    • 若是表A的主关键字是表B中的字段,则该字段成为表B的外键
    • 保持数据的一致性,完整性,主要目的是控制存储在外键表中的数据
    • 使两张表造成关联,外键只能引用外表中列的值或使用空值

02-代码实现DDL语句

  • 建立swift项目
  • 导入系统框架sqlite3.tdb(sqlite3.dylib)
  • 在Build Setting中搜索bridging,找到Objective-C Bridging Header,设置一个.h文件路径为桥接文件
  • 打开桥接文件,导入头文件"sqlite3.h"
  • 代码实现
    • 打开数据库
      • 获取沙盒路径,而后建立数据库的存储路径
      • SQlite3数据库文件的扩展名没有一个标准定义,比较流行的选择是.sqlite三、.db、.db3
    • 使用打开的数据库,执行DDL语句,建立一个数据库表
    • 使用打开的数据库,执行DDL语句,删除一个数据库表
    • 将数据库操做封装成一个工具类

03-代码实现DML语句

1.insert绑定参数

  • 准备语句(prepared statement)对象
    • 准备语句对象表明一个简单SQL语句对象的实例,这个对象一般被称为"准备语句"或者"编译好的SQL语句"或者就直接称为"语句"
  • 操做历程:
    • 使用sqlite3_prepare_v2或者相关的函数建立这个对象,若是执行成功,则返回SQLITE_OK,不然返回一个错误码
    • 使用sqlite3_bind_*()给宿主参数绑定值
    • 经过调用sqlite3_step()一次或屡次来执行这个sql
      • 对于DML语句,若是执行成功,返回SQLITE_DONE
      • 对于DQL语句,经过屡次执行获取结果集,继续执行的条件是返回值SQLITE_ROW
    • 使用sqlite3_reset()重置这个语句,而后回到第2步,这个过程作0次或屡次
    • 使用sqlite3_finalize()销毁这个对象,防止内存泄漏

2.insert插入数据优化

  • sqlite_exec直接执行和未拆解"准备语句"平均执行时间差很少
    • sqlite_exec函数是对"准备语句"的封装
    • (预处理语句->绑定参数->执行语句->重置语句->释放语句)
  • 拆解后的"准备语句"执行,效率明显高了一些,主要缘由是真准遵循了"准备语句"的操做流程
  • 虽然按步骤使用"准备语句",可是执行效率依然不如意
    • 缘由分析:每当SQL调用执行方法执行了一个语句,都会开启一个叫事务的东西,执行完毕后再提交事务,也就是说,若是执行了10000次SQL语句,就打开和提交了10000次事务,因此形成耗时严重.
    • 解决方案:只要在执行多个SQL语句以前,手动开启事务,在执行完毕以后,手动提交事务,这样再调用SQL方法执行语句时,就不会再自动开启和提交事务.
    • 优化后的结果:插入10000条数据,大概耗时0.07秒
  • 得出结论:
    • 若是插入大量数据,请务必手动开启/提交事务
    • 根据不一样状况,选择使用sqlite3_exec或者"准备语句",若是操做单条语句,使用前者,若是大批量操做,选择后者

04-代码实现事务

  • 概念:
    • 事务(Transaction)是并发控制的单位,是用户定义的一个操做序列.
    • 这些操做要么都作,要么都不作,是一个不可分割的工做单位.
    • 经过事务,能够将逻辑相关的一组操做绑定在一块儿,保持数据的完整性.
  • 事务一般是以begin transaction开始,以commit transaction或者rollback transaction结束
    • commit表示提交,即提交事务的全部操做.具体的说就是将事务中全部对数据库的更新写回磁盘上的物理数据库中去,事务正常结束.
    • rollback表示回滚,即在事务运行得过程当中发生了某些故障,事务不能继续进行,系统将事务中对数据库的全部已完成的操做所有撤销,回滚到事务开始的状态.

05-代码实现DQL语句

1.使用sqlite3_exec

  • 做用:能够经过回调来获取结果,步骤相对来讲简单,结果数据类型没有特定类型(id)
  • 参数说明
    • 参数1:一个打开的数据库
    • 参数2:须要执行的SQL语句
    • 参数3:查询结果回调(执行0次或屡次)
      • 参数1:参数4的值
      • 参数2:列的个数
      • 参数3:结果值的数组
      • 参数4:全部列的名称数组
      • 返回值:0表明继续执行直到结束,1表明执行1次
    • 参数4:回调函数的第一个值
    • 参数5:错误信息

2.使用"准备语句"

  • 做用:能够处理不一样特定类型,步骤相对来讲复杂
  • 步骤:
    • 经过预处理函数,获取"准备语句" sqlite3_prepare
    • 不断执行"准备语句",直到无结果集 while sqlite3_step(stmt) == SQLITE_ROW
    • 获取列的类型 sqlite3_column_type
    • 根据每列的类型取出不一样的值
      • sqlite3_column_int64 SQLITE_INTEGER
      • sqlite3_column_double SQLITE_FLOAT
      • sqlite3_column_text SQLITE_TEXT
        • 须要转换下字符串
        • let cText = UnsafePointer (sqlite3_column_text(stmt,col))
        • let text = String(CString:cText,encoding:NSUTF8StringEncoding)
      • NSNull() SQLITE_NULL
    • 释放资源 sqlite3_finalize

06-FMDB基本使用

1.什么是FMDB

  • FMDB是iOS平台的SQLite框架
  • FMDB以OC的方式封装了SQLite的C语言API

2.FMDB有什么优点

  • 使用起来更加面向对象,省去了不少麻烦,冗余的C语言代码
  • 提供了多线程安全的数据库操做方法,有效地防止数据混乱

3.安装方式

  • Cocoapods:"use_framework!",使用dynamic frameworks的方式集成
  • 手动集成(swift):
    • 导入FMDB文件
    • 导入系统依赖库sqlite3.0.tbd
    • 创建桥接文件,并导入须要的头文件

4.核心类

  • FMDatabase
    • 一个FMDatabase对象就表明一个独立的SQLite数据库
    • 用来执行SQL语句
  • FMResultSet
    • 使用FMDatabase执行查询后的结果集
  • FMDatabaseQueue
    • 用于在多线程中执行多个查询或更新,它是线程安全的

5.使用步骤

  • 打开数据库
    • 经过指定SQLite数据库文件路径来建立FMDatabase对象
    • 文件路径有3种状况:
      • 具体文件路径(若是不存在会自动建立)
      • 空字符串@""(会在临时目录建立一个空的数据库,当FMDatabase链接关闭时,数据库文件也被删除)
      • nil(会建立一个内存中临时数据库,当FMDatabase链接关闭时,数据库会被销毁)
    • FMDatabase *db = [FMDatabase databaseWithPath:path];
    • if([db open]) { NSLog(@"打开成功"); }
  • 执行更新
    • 在FMDB中,除查询之外的全部操做,都称为"更新"
    • create/drop/insert/update/delete等
    • 使用executeUpdate方法执行更新
  • 执行查询
  • 关闭数据库:database.close();

07-FMDatabaseQueue

  • FMDatabase这个类是线程不安全的,若是在多个线程中同时使用一个FMDatabase实例,会形成数据混乱等问题
  • 为了保证线程安全,FMDB提供方便快捷的FMDatabaseQueue类
  • FMDatabaseQueue的建立
    • FMDatabaseQueue *queue = [FMDatabaseQueue databaseQueueWithPath:path];
  • 简单使用
    • [queue inDatabase:^(FMDatabase *db){在里面经过db执行SQL语句获取结果,对数据进行处理}];
  • 使用事务
    • [queue inTransaction:^(FMDatabase *db,BOOL *rollback){在里面经过db执行SQL语句获取结果,对数据进行处理}];
相关文章
相关标签/搜索