热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SQLite入门教程

原文:SQLiteTutorial:GettingStarted注意:在2016-04-06已经更新到Xcode7.3iOS9.3和Swift2.2。在软件开发的世界中,在你需要对

原文:SQLite Tutorial: Getting Started

注意:在2016-04-06已经更新到 Xcode 7.3 iOS 9.3Swift 2.2

在软件开发的世界中,在你需要对你的 app 进行数据持久化前开发它并不用花费很多时间。在许多情况下,这是以数据结构的形式出现的,但你如何更有效地存储它?

幸运的是,一些伟大的先行者已经开发了关于访问存储在数据库中的结构化数据和写入语言的功能的解决方案。这个 SQLite 教程向您展示了如何快速使用 Swift 在流行平台工作上使用 SQLite 数据库,在 iOS 平台 SQLite 是默认可用的。如果你熟悉 Core Data 的话,你就会知道 SQLite 一些和 Core Data 类似的最常见持久化对象图的方法。

在本SQLite的教程中,您将学习到以下几种如何执行数据库的操作:

  • 创建和连接一个数据库
  • 创建一个表
  • 插入行
  • 更新行
  • 删除行
  • 查询数据库
  • 处理 SQLite 错误

在学完这些基本的如何执行操作后,你会看到如何用一种更加 Swift 的方式将它们包装起来。它会帮助在你的应用中写更加抽象 APIs ,这样的话就可以大量的避免直接面对 SQLite 中的C语言的 APIs

最后,我将简单介绍流行的开源资源 Swift 封装的 SQLite.swift 的底层框架内是如何工作的。

Note: 数据库,甚至是SQLite自身,是巨大的主题,所以它们的很多内容超出了本教程的范围。本文假定你对于关系数据库的思想有基本的了解,你主要是来学习如何结合Swift来使用SQLite。

开始

下载这个 SQLite 教程的 启动项目 ,打开 SQLiteTutorial.xcworkspace。根据项目的导航栏打开 Tutorial.playground。你会马上注意到 import SQLite 那行有一个错误信息,你至少要编译项目一次,可以使用 Command + B 。这是因为需要工作空间的配置信息来创建一个模块,这样SQLite才可以运行在 playground

Note: SQLite是不正确的模块,你不能在你的项目中调用导入SQLite模块,不要被 import SQLite 这行误导;相反,你可以使用一个桥接的头部。

playground 打开的时候,设置它为手动运行,而不是自动运行:

《SQLite 入门教程》 sqliteswift_manually_run_payground.png

这将有助于确保按你想那样运行SQL命令。

在这个页面的顶部你也可以看到一个 destroyPart1Database() 函数的调用;你可以安全地忽略这个,由于每次运行 playground 时,数据库文件会被破坏。这将确保你在这个SQLite教程所有语句成功执行。

你的 playground 的文件系统中,在需要的地方写SQLite数据库文件。可以在终端中运行下面的命令,为您的 playground 创建数据目录:

mkdir -p ~/Documents/Shared\ Playground\ Data/SQLiteTutorial

我为什么要选择SQLite?

对的,在iOS中 SQLite 不是唯一保存数据的途径。除了 Core Data ,还有很多数据持久化的选择,包括 Realm , Couchbase Lite , Firebase 和 NSCoding 。

每一个都有自己的优点和缺点,包括 SQLite 自身。在没有数据持久层,作为开发者,基于你的应用要求来决定选择哪个选项。

SQLite 确实有一定的优势:

  • 在iOS的应用程序包没有增加额外的开销
  • 尝试和测试;第一个版本在2000年8月发布
  • 开源
  • 对于数据库开发人员和管理员熟悉的查询语言
  • 跨平台

SQLite 的优劣可以说非常直观和明显,所以这些我们会留下给你自己研究!

C的API

这部分的 SQLite 教程通过最常用和基本的 SQLite 的API来引导你。你会很快意识到用 Swift 的方法来包装C语言的API是个很好的想法,但是坐下来,我们先通过C语言去实现;你将在本教程的第二部分做一些 SQLite 的包装。

打开一个连接

在你做任何事情之前,你都需要先创建一个数据库的连接。

在开始部分的 playground 上添加如下方法:

func openDatabase() -> COpaquePointer {
var db: COpaquePointer = nil
if sqlite3_open(part1DbPath, &db) == SQLITE_OK {
print("Successfully opened connection to database at \ (part1DbPath)")
return db
} else {
print("Unable to open database. Verify that you created the directory described " + "in the Getting Started section.")
XCPlaygroundPage.currentPage.finishExecution()
}
}

上面的方法调用 sqlite3_open() 来打开或创建一个新的数据库文件,如果成功,将返回一个 COpaquePointer ;它是一个 Swift 类型,以为C指针不能直接在Swift中表示。当你调用这个方法,您将会捕获到返回的指针,用于与数据库交互。

许多的SQLite函数返回一个 Int32 结果,大多数这些代码被定义为在SQLite库常数,例如, SQLITE_OK 代表结果代码0。你可以在SQLite的网站上找到一个关于不同结果代码的列表。

去打开数据库,在你的 playground 上添加以下行:

let db = openDatabase()

按下 Play 按钮运行playground,观察控制台输出。如果控制台没有打开,按下左边的按钮来运行:

《SQLite 入门教程》

如果 openDatabase() 返回成功,你会看到以下输出内容:

Successfully opened connection to database at /Users/username/
Documents/Shared Playground Data/SQLiteTutorial/Part1.sqlite

username 是你的 Home 目录。

创建表

现在你已经连接上数据库文件了,你可以创建一张表。您将使用一个非常简单的表来存储联系人。

下面这张表由两个列组成, id 的的数据类型是 INT 是表的主键, Name 的数据类型是 CHAR(255) .

《SQLite 入门教程》 sqliteswift_table_diagram.png

添加下面的字符串,是创建表必要的SQL语句:

let createTableString = "CREATE TABLE Contact(" + "Id INT PRIMARY KEY NOT NULL," + "Name CHAR(255));"

下一步,添加此方法来执行创建表的SQL语句:

func createTable() {
// 1
var createTableStatement: COpaquePointer = nil
// 2
if sqlite3_prepare_v2(db, createTableString, -1, &createTableStatement, nil) == SQLITE_OK {
// 3
if sqlite3_step(createTableStatement) == SQLITE_DONE {
print("Contact table created.")
} else {
print("Contact table could not be created.")
}
} else {
print("CREATE TABLE statement could not be prepared.")
}
// 4
sqlite3_finalize(createTableStatement)
}

一步一步来分解:

  1. 首先,你创建一个指针便于第二步的引用。

  2. sqlite3_prepare_v2() 函数将 SQLite 语句编译成字节码并返回一个状态码,在执行任意数据库语句前这是很重要的一步。如果你对这个感兴趣,你可以在这里按查看更多,通过检查返回的状态码来确保编译成功。如果是这样的话,这个过程将移动到步骤3;否则,控制台会打印一条语句无法编译的消息。

  3. sqlite3_step() 运行已编译的语句,在这种情况下,只有当有一个结果时,才执行一次。之后在这个 SQLite 的教程它是必要的步骤,你会多次看到它的声明。

  4. 你必须总是调用 sqlite3_finalize() 编译语句删除它,避免资源泄漏。一旦一个语句已经完成,你就不应该再使用它了。

现在,你可以添加下面的方法在 playground 中调用:

createTable()

运行 playground ,你会在控制台上看下面的信息出现:

Contact table created

现在你的数据库里有一张表了,是时间往里面添加些数据了。添加一行数据, id1NameRay

插入一些数据

添加下面的SQL语句到你的 playground 的底部:

let insertStatementString = "INSERT INFO Contact (Id, Name) VALUES (?, ?);"

如果你没有太多开发SQL的经验也许看起来有一点奇怪。为什么值是问号呢?

还记得上面使用的 sqlite3_prepare_v2() 编译的句子?这个 ? 的语法是告诉编译器,当实际执行语句时,将提供真正的值。

这是有性能上的考虑,让你提前编译语句,这可能是一个性能增益,因为编译是一个昂贵的操作。编译后的语句可以重新使用不同的值。

接下来,创建下面的方法在你的 playground

func insert() {
var insertStatement: COpaquePointer = nil // 1
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
let id: Int32 = 1
let name: NSString = "Ray" // 2
sqlite3_bind_int(insertStatement, 1, id)
// 3
sqlite3_bind_text(insertStatement, 2, name.UTF8String, -1, nil) // 4
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
} else {
print("INSERT staremnet could not be prepared.")
}
// 5
sqlite3_finalize(insertStatement)
}

下面介绍上面的方法是如何工作的:

  1. 首先,编写SQL语句并验证是否正确;
  2. ? 占位符得地方定义值。函数的名字 sqlite3_bind_int() – 意味着你绑定一个 int 值的声明。函数的第一个参数是绑定到的语句,而第二个参数是一个非零的索引用于绑定 ? 的位置。第三个和最后一个参数是值本身。这个绑定调用返回一个状态代码,但现在你假设它成功了的;
  3. 执行相同的绑定过程,但是这一次是一个文本值。在这个调用里有两个额外的参数;在这个SQLite的教程里你可以简单设为 -1nil 。如果你有兴趣,你可以在这里阅读更多关于绑定参数;
  4. 使用 sqlite3_step() 函数执行的语句和验证完成;
  5. 一如既往,最后确定声明。如果您要插入多个联系人,您可能会保留该语句,并使用不同的值重新使用它。

下一步,在 playground 中调用下面这个新添加的方法:

insert()

运行你的 playground 和验证您看到您在控制台输出:

Successfully inserted row.

挑战:多条插入

挑战时间!你的任务是更新 insert() 函数使它可以插入一组联系人。

作为一个提示,你需要重新编写 SQL 语句,用 sqlite3_reset() 返回到它的初始状态再执行一遍。

解决方案:插入多行

func insert() {
var insertStatement: COpauePointer = nil
// 1
let names: [NSString] = ["Ray", "Chirs", "Martha", "Danielle"] if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
// 2
for (index, name) in names.enumerate() {
// 3
let id = Int32(index + 1)
sqlite3_bind_int(insertStatement, 1, id)
sqlite3_bind_text(insertStatement, 2, name.UTF8String, -1, nil)
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("Successfully inserted row.")
} else {
print("Could not insert row.")
}
// 4
sqlite3_reset(insertStatement)
}
sqlite3_finalize(insertStatement)
} else {
print("INSERT statement could not be prepared.")
}
}

推荐阅读
  • MicrosoftDeploymentToolkit2010部署培训实验手册V1.0目录实验环境说明3实验环境虚拟机使用信息3注意:4实验手册正文说 ... [详细]
  • [转]doc,ppt,xls文件格式转PDF格式http:blog.csdn.netlee353086articledetails7920355确实好用。需要注意的是#import ... [详细]
  • 字节流(InputStream和OutputStream),字节流读写文件,字节流的缓冲区,字节缓冲流
    字节流抽象类InputStream和OutputStream是字节流的顶级父类所有的字节输入流都继承自InputStream,所有的输出流都继承子OutputStreamInput ... [详细]
  • 本文介绍了如何使用Python的Paramiko库批量更新多台服务器的登录密码。通过示例代码展示了具体实现方法,确保了操作的高效性和安全性。Paramiko库提供了强大的SSH2协议支持,使得远程服务器管理变得更加便捷。此外,文章还详细说明了代码的各个部分,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在软件开发过程中,经常需要将多个项目或模块进行集成和调试,尤其是当项目依赖于第三方开源库(如Cordova、CocoaPods)时。本文介绍了如何在Xcode中高效地进行多项目联合调试,分享了一些实用的技巧和最佳实践,帮助开发者解决常见的调试难题,提高开发效率。 ... [详细]
  • 在本文中,我们将探讨如何在Docker环境中高效地管理和利用数据库。首先,需要安装Docker Desktop以确保本地环境准备就绪。接下来,可以从Docker Hub中选择合适的数据库镜像,并通过简单的命令将其拉取到本地。此外,我们还将介绍如何配置和优化这些数据库容器,以实现最佳性能和安全性。 ... [详细]
  • 在 CentOS 7 系统中安装 Scrapy 时遇到了一些挑战。尽管 Scrapy 在 Ubuntu 上安装简便,但在 CentOS 7 上需要额外的配置和步骤。本文总结了常见问题及其解决方案,帮助用户顺利安装并使用 Scrapy 进行网络爬虫开发。 ... [详细]
  • 本文深入探讨了NoSQL数据库的四大主要类型:键值对存储、文档存储、列式存储和图数据库。NoSQL(Not Only SQL)是指一系列非关系型数据库系统,它们不依赖于固定模式的数据存储方式,能够灵活处理大规模、高并发的数据需求。键值对存储适用于简单的数据结构;文档存储支持复杂的数据对象;列式存储优化了大数据量的读写性能;而图数据库则擅长处理复杂的关系网络。每种类型的NoSQL数据库都有其独特的优势和应用场景,本文将详细分析它们的特点及应用实例。 ... [详细]
  • iOS 设备唯一标识获取的高效解决方案与实践
    在iOS 7中,苹果公司再次禁止了对MAC地址的访问,使得开发者无法直接获取设备的物理地址。为了在开发过程中实现设备的唯一标识,苹果推荐使用Keychain服务来存储和管理唯一的标识符。此外,还可以结合其他技术手段,如UUID和广告标识符(IDFA),以确保设备的唯一性和安全性。这些方法不仅能够满足应用的需求,还能保护用户的隐私。 ... [详细]
  • HBase Java API 进阶:过滤器详解与应用实例
    本文详细探讨了HBase 1.2.6版本中Java API的高级应用,重点介绍了过滤器的使用方法和实际案例。首先,文章对几种常见的HBase过滤器进行了概述,包括列前缀过滤器(ColumnPrefixFilter)和时间戳过滤器(TimestampsFilter)。此外,还详细讲解了分页过滤器(PageFilter)的实现原理及其在大数据查询中的应用场景。通过具体的代码示例,读者可以更好地理解和掌握这些过滤器的使用技巧,从而提高数据处理的效率和灵活性。 ... [详细]
  • HBase在金融大数据迁移中的应用与挑战
    随着最后一台设备的下线,标志着超过10PB的HBase数据迁移项目顺利完成。目前,新的集群已在新机房稳定运行超过两个月,监控数据显示,新集群的查询响应时间显著降低,系统稳定性大幅提升。此外,数据消费的波动也变得更加平滑,整体性能得到了显著优化。 ... [详细]
  • NoSQL数据库,即非关系型数据库,有时也被称作Not Only SQL,是一种区别于传统关系型数据库的管理系统。这类数据库设计用于处理大规模、高并发的数据存储与查询需求,特别适用于需要快速读写大量非结构化或半结构化数据的应用场景。NoSQL数据库通过牺牲部分一致性来换取更高的可扩展性和性能,支持分布式部署,能够有效应对互联网时代的海量数据挑战。 ... [详细]
  • 分布式一致性算法:Paxos 的企业级实战
    一、简介首先我们这个平台是ES专题技术的分享平台,众所周知,ES是一个典型的分布式系统。在工作和学习中,我们可能都已经接触和学习过多种不同的分布式系统了,各 ... [详细]
  • 分享一下最近写的ReactNative的SSHSFTP组件,iOS端封装了NMSSH,Android端封装了JSch。支持SSH执行命令、实时Shell ... [详细]
  • 我要用Direct3D建立一个虚拟的屋子,然后把我的视角放到屋子里面,并且可以水平旋转,就象是虚拟现实空间那样。其实就跟DOOM类游戏一样。并且能够用PICK函数去选取在指定点 ... [详细]
author-avatar
Still丶某某_546
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有