本文主要介绍如何查询 SQLite 结果集,以及封装 SQLite 的操作方法。

准备测试代码

/// 从数据库中加载 person 数组
class func persons() -> [Person]? {// 1. 准备 SQLlet sql = "SELECT id, name, age, height FROM T_Person;"// 2. 访问数据库// 3. 返回结果return nil
}

在 SQLiteManager 中添加查询语句,准备结果集

/// 执行 SQL 返回查询结果集
///
/// - parameter sql: 任意给定的 SELETE 查询 SQL
func execRecordSet(sql: String) {// 1. 预编译 SQL/**参数1. 已经打开的数据库句柄2. 要执行的 SQL3. 以字节为单位的 SQL 最大长度,传入 -1 会自动计算4. SQL 语句句柄- 后续针对当前查询结果的操作全部基于此句柄- 需要调用 sqlite3_finalize 释放5. 未使用的指针地址,通常传入 nil*/var stmt: COpaquePointer = nilif sqlite3_prepare_v2(db, sql, -1, &stmt, nil) != SQLITE_OK {print("SQL 错误")return}print("SQL 正确")// 2. 遍历集合// 3. 释放语句句柄 - 很重要,否则会内容泄漏sqlite3_finalize(stmt)
}

代码小结

  • 这一部分的工作可以看作是对字符串的 SQL 语句进行编译,并且检查是否存在语法问题
  • 编译成功后通过 sqlite3_step 执行 SQL,每执行一次,获取一条记录
  • 通过 while 循环直至执行完毕
  • 注意,指令执行完毕后需要释放

单步执行

// 2. 单步执行获取结果集内容
var row = 0
while sqlite3_step(stmt) == SQLITE_ROW {print("记录 \(row++)")
}

新建函数负责从 stmt 中获取一条完整的记录

/// 从 stmt 中获取一条完整的记录
///
/// - parameter stmt: stmt
private func record(stmt: COpaquePointer) {print("记录")
}

获取单条记录

所有函数都是以 sqlite3_column_ 开始

  • 获取列数
// 查询结果列数
let colCount = sqlite3_column_count(stmt)
print("列数 \(colCount)")
  • 遍历每一列获取对应的列名数据类型
// 遍历每一列
for col in 0..<colCount {// 列名let cName = sqlite3_column_name(stmt, col)let name = String(CString: cName, encoding: NSUTF8StringEncoding) ?? ""// 数据类型let type = sqlite3_column_type(stmt, col)print("列名 \(name) 值 \(value)")
}

根据不同的数据类型转换对应的数值

  • 小数
var value: AnyObject?
switch type {
case SQLITE_FLOAT:value = sqlite3_column_double(stmt, col)
default:print("不支持的数据类型")
}print("列名 \(name) 值 \(value)")
  • 整数
case SQLITE_INTEGER:value = Int(sqlite3_column_int64(stmt, col))
  • 字符串
case SQLITE3_TEXT:let cText = UnsafePointer<Int8>(sqlite3_column_text(stmt, col))value = String(CString: cText, encoding: NSUTF8StringEncoding)
  • 空值
case SQLITE_NULL:value = NSNull()
  • 增加返回值和字典,调整后的代码如下:
/// 从 stmt 中获取当前记录的完整内容
///
/// - parameter stmt: stmt 句柄
private func record(stmt: COpaquePointer) -> [String: AnyObject] {// 1. 获取查询结果列数let colCount = sqlite3_column_count(stmt)// 单条记录字典var row = [String: AnyObject]()// 2. 遍历所有列,获取每一列的信息for col in 0..<colCount {// 1> 获取列名let cName = sqlite3_column_name(stmt, col)let name = String(CString: cName, encoding: NSUTF8StringEncoding) ?? ""// 2> 获取每列数据类型let type = sqlite3_column_type(stmt, col)// 3> 根据数据类型获取对应结果var value: AnyObject?switch(type) {case SQLITE_FLOAT:value = sqlite3_column_double(stmt, col)case SQLITE_INTEGER:value = Int(sqlite3_column_int64(stmt, col))case SQLITE3_TEXT:let cText = UnsafePointer<Int8>(sqlite3_column_text(stmt, col))value = String(CString: cText, encoding: NSUTF8StringEncoding)case SQLITE_NULL:value = NSNull()default:print("不支持的数据类型")}//            print("列名 \(name) 值 \(value)")row[name] = value ?? NSNull()}return row
}

完善 execRecordSet 函数

  • 完善 execRecordSet 函数
/// 执行 SQL 返回查询结果集
///
/// - parameter sql: 任意给定的 SELETE 查询 SQL
func execRecordSet(sql: String) -> [[String: AnyObject]]? {// 1. 预编译 SQL/**参数1. 已经打开的数据库句柄2. 要执行的 SQL3. 以字节为单位的 SQL 最大长度,传入 -1 会自动计算4. SQL 语句句柄- 后续针对当前查询结果的操作全部基于此句柄- 需要调用 sqlite3_finalize 释放5. 未使用的指针地址,通常传入 nil*/var stmt: COpaquePointer = nilif sqlite3_prepare_v2(db, sql, -1, &stmt, nil) != SQLITE_OK {print("SQL 错误")return nil}// 创建结果数组var rows = [[String: AnyObject]]()// 2. 遍历集合while sqlite3_step(stmt) == SQLITE_ROW {// 将单条记录字典添加到结果数组中rows.append(record(stmt))}// 3. 释放语句句柄 - 很重要,否则会内容泄漏sqlite3_finalize(stmt)// 4. 返回结果数组return rows
}
  • 在 Person 模型中加载 Person 列表
/// 从数据库中加载 person 数组
class func persons() -> [Person]? {// 1. 准备 SQLlet sql = "SELECT id, name, age, height FROM T_Person;"// 2. 访问数据库获得字典数组guard let rows = SQLiteManager.sharedManager.execRecordSet(sql) else {return nil}// 3. 遍历字典数组 - 字典转模型var arrayM = [Person]()for row in rows {arrayM.append(Person(dict: row))}// 4. 返回结果集合return arrayM
}
  • 测试代码
print((Person.persons() ?? []) as NSArray)

Swift 中使用 SQLite——查询数据相关推荐

  1. Swift 中使用 SQLite——新增数据

    本文重点介绍两个方面,1.新增数据,2.获取自动增长 ID. 建立 Person.swift 数据模型 /// 个人模型 class Person: NSObject {// MARK: - 模型属性 ...

  2. Swift 中使用 SQLite——批量更新(事务处理)

    本文是Swift 中使用 SQLite系列的收官之作,介绍一下在数据库中的批量更新. 事务 在准备做大规模数据操作前,首先开启一个事务,保存操作前的数据库的状态 开始数据操作 如果数据操作成功,提交事 ...

  3. Swift 中使用 SQLite——打开数据库

    关于Swift中使用SQLite,接下来可能会分别从打开.增.删.改.查,几个方面来介绍SQLite的具体使用,这一篇重点介绍一下如何打开. 定义全局数据库访问句柄 /// 全局数据库访问句柄 pri ...

  4. android用于查询数据的方法,android: SQLite查询数据

    掌握了查询数据的方法之后,你也就将数据库的 CRUD 操 作全部学完了.不过千万不要因此而放松,因为查询数据也是在 CRUD 中最复杂的一种 操作. 我们都知道 SQL 的全称是 Structured ...

  5. 【Spring中使用MongoTemplate查询数据】

    MongoDB初体验:Spring中使用MongoTemplate查询数据 - ㄓㄤㄑㄧㄤ - 博客园

  6. 博图WINCC报表(SQL数据库的建立,TIA_wincc在数据库中保存和查询数据,调用Excel模板把数据保存到指定的位置)

    这里写目录标题 目录 一.概述 1.1 前言 1.2 主要功能 1.3 使用的软件 二. SQL server建库和建表 2.1.SQL server建库 2.2SQL server建表 三.建立wi ...

  7. 「FastAdmin」fastadmin二次开发中如何自定义查询数据

    fastadmin二次开发中如何自定义查询数据 问题背景:最近做一个网站的过程中遇到了一个需求:对于不同用户组的用户,显示的数据要根据权限来筛选.问题看起来不是很难,文档和社区中已经给了足够的提示,我 ...

  8. python怎么输出结果_如何在python中打印SQLite查询的结果?

    我试图打印这个SQLite查询的结果来检查它是否已经将数据存储在数据库中.目前它只打印None.有没有办法在Microsoft Word或LibreOffice等程序中打开数据库.只是为了看看它是否已 ...

  9. ES中实现分页查询数据并返回想要的字段

    在日志收集系统中,最近需要通过httpclient获取es中的日志信息,所以学习了一些es的查询语句方面的用法: 分页 分页的本质 分页的本质是从"大的数据集"中取出一部分.比如1 ...

最新文章

  1. NSURLErrorRelatedURLSessionTaskErrorKey
  2. stm32中断向量控制器
  3. atitit.loading的设计与实现控件选型attilax 总结
  4. 基类的构造函数也可以被继承_「C++ Primer plus 心得」13.类继承
  5. libevent源码学习-----时间管理
  6. hdoj1428 -- 漫步校园 (记忆化搜索)
  7. linux nat冲突,Linux系统下的NAT及防火墙的混合应用
  8. oracle查询最高一条记录,oracle 查询已有记录,上一条记录,下一条记录
  9. 简化Swagger使用的自制Starter:spring-boot-starter-swagger,欢迎使用和吐槽
  10. Log4Net异常日志记录在asp.net mvc3.0的应用
  11. java蘑菇岛种子_我的世界:Java版玩家笑开了怀,4个地图种子,2个内陆蘑菇岛...
  12. 想和你去吹吹风(张学友演唱歌曲)
  13. 分享利用QQ群淘宝客引流变现技巧
  14. python实现批量图片文字识别(ocr)
  15. 赠书 | 供应链金融模式有哪些?区块链在供应链金融中如何应用?
  16. 如何用outlook添加qq邮箱账户
  17. Elastic认证特训营 难点解读04——集群问题排查实战指南
  18. vue3+ant design vue 动态加载Icon图标
  19. 计算机win10搜不到wifi,笔记本win10系统搜不到wifi网络怎么回事|笔记本搜不到wifi网络的解决方法...
  20. Python中字符串的驻留机制和常用方法

热门文章

  1. 码农技术炒股之路——抓取日线数据、计算均线和除权数据
  2. 解决Windows7下vs2008 Active control test container 不能运行的问题
  3. 【linux工具】ldconfig:linux配置动态链接库
  4. Java学习总结:28
  5. php 腾讯云实时音视频,腾讯云视频 -实时音视频学习日志
  6. 第二章 Servlet核心技术 实训二
  7. 五种常用的JavaScript自定义对象方式
  8. 方法的运用_企业如何运用论坛做营销,千享科技分享技巧方法
  9. 样式集(六)仿微信通讯录样式
  10. Swift 条件编译,编译标记