热门标签 | 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.")
}
}

推荐阅读
  • 1.sqlite3xxx.db2..modecsv3..importcsv文件表名例:.importcity.csvcity4..quit退出注1:不要忘了开首的点注2:这条语句不 ... [详细]
  • SQLite3是一个广泛使用的数据库,从linux,windows到安卓都有SQLite的应用。本文介绍SQLite3在windows上的编译。SQLite3提供了多种源代码的下载 ... [详细]
  • 本文将介绍如何使用 Go 语言编写和运行一个简单的“Hello, World!”程序。内容涵盖开发环境配置、代码结构解析及执行步骤。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • 深入理解 SQL 视图、存储过程与事务
    本文详细介绍了SQL中的视图、存储过程和事务的概念及应用。视图为用户提供了一种灵活的数据查询方式,存储过程则封装了复杂的SQL逻辑,而事务确保了数据库操作的完整性和一致性。 ... [详细]
  • 数据库内核开发入门 | 搭建研发环境的初步指南
    本课程将带你从零开始,逐步掌握数据库内核开发的基础知识和实践技能,重点介绍如何搭建OceanBase的开发环境。 ... [详细]
  • 使用C#开发SQL Server存储过程的指南
    本文介绍如何利用C#在SQL Server中创建存储过程,涵盖背景、步骤和应用场景,旨在帮助开发者更好地理解和应用这一技术。 ... [详细]
  • 本文详细介绍了Java编程语言中的核心概念和常见面试问题,包括集合类、数据结构、线程处理、Java虚拟机(JVM)、HTTP协议以及Git操作等方面的内容。通过深入分析每个主题,帮助读者更好地理解Java的关键特性和最佳实践。 ... [详细]
  • 本文详细介绍了C语言中的指针,包括其基本概念、应用场景以及使用时的优缺点。同时,通过实例解析了指针在内存管理、数组操作、函数调用等方面的具体应用,并探讨了指针的安全性问题。 ... [详细]
  • 解析SQL查询结果的排序问题及其解决方案
    本文探讨了为什么某些SQL查询返回的数据集未能按预期顺序排列,并提供了详细的解决方案,帮助开发者理解并解决这一常见问题。 ... [详细]
  • 本文探讨了如何使用自增和自减运算符遍历二维数组中的元素。通过实例详细解释了指针与二维数组结合使用的正确方法,并解答了常见的错误用法。 ... [详细]
  • 云屏系统基于嵌入式微系统msOS,旨在解决当前嵌入式彩屏GUI编程中硬件要求高、软件开发复杂、界面效果不佳等问题。该系统通过结合MCU和Android技术,利用Html5+JavaScript实现高效、易用的图形用户界面开发,使嵌入式开发人员能够专注于业务逻辑。 ... [详细]
  • Android和iOS的数据库都是用SQLite来实现.一,SQLite数据库简介:轻量级:SQLite数据库是一个轻量级的数据库,适用于少量数据的CURD;文件本质:SQL ... [详细]
  • SQLite–DISTINCT关键字使用SQLiteDISTINCT关键字与SELECT语句来消除所有重复的记录和获取唯一的记录。可能存在一种情况,当你有多个表中重复的记录。获取这 ... [详细]
  • SQLite Select语句
    基本语法:SELECTcolumn1,column2,columnNFROMtable_name;若想获取所有可用字段,则如下:SELECT*FROMtable_name;假设:i ... [详细]
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社区 版权所有