sqlite.swift应用简介

来源:互联网 发布:淘宝的宝贝卖点怎么写 编辑:程序博客网 时间:2024/06/05 07:10

    SQLite3是一款非常轻便易用并且开源的嵌入式数据库,而SQLite3官方所提供的API接口是用C来提供的,如果用swift进行macOS或是iOS开发的话,就会很不方便,因此有一个国外的大神用swift封装了SQLite提供的API,并且分享在了GitHub上,称之为sqlite.swift,并且最新版本也使用了swift3的语法。原版的说明文档在此:https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md#setters,不过对于像我一样英语不太好的朋友来说,可能阅读起来是个障碍。所以这篇文章就来介绍一下sqlite.swift的一些常用的功能和用法。

1.安装

    首先是导入,官方介绍了4种导入的方法,最简单(也是最手动的)其实是最后一种,就是直接下载然后手动导入,这种导入方法我尝试过,开发时没有什么问题,但是在发布打包的时候无论如何都不能运行打包后的app,不知道究竟是哪里的设置没有搞对。所以本人推荐的是使用CocoaPods进行安装导入工程,这样做在工程开发完毕后打包出来的app亲测可用的。关于CocoaPods的安装方法这里不多做赘述,网上的教程非常多,如果有疑问的话欢迎留言讨论。

    那么第一步,我们需要建立一个工程(iOS或macOS),然后打开终端,进入到项目工程的根目录下,创建一个文件叫"Podfile":

然后用一个你喜欢的文本编辑器打开它,习惯用终端的朋友当然也可以用vim或者nano直接打开。打开之后在文件中写入:

use_frameworks!target 'sqlite_test' do    pod 'SQLite.swift', '~> 0.11.3'end
其中的“sqlite_test”换成你实际的工程名称,然后在终端执行:

pod install --repo-update
等待安装完毕(如果是初次安装需要一段时间从网上下载),如果在整个运行过程中没有出现红色的文字段,就说明安装成功了


然后在你的项目中会多了一些文件,其中有一个扩展名是xcworkspace的,我们以后打开工程就用它。


2.创建数据库

如果要使用sqlite库中的内容,必须在程序文件前引入该库:
import SQLite
然后连接数据库:
try? dbCon = Connection("/test/db1.sqlite3", readonly: false)
其中第一个参数是数据库的路径,第二个参数是制定数据库是否为只读,如果是false的话可以省略

3.执行SQL语句

    虽然sqlite.swift用swift语言封装了绝大多数的数据库功能,但是有的时候我们还是需要自己来执行SQL语句的,执行SQL语句分为两种情况,一种是命令语句,比如说建立表格,插入数据,或者是打开外键约束功能之类的,我们仅仅是要执行一句指令,而不需要得到什么数据,如果是这种类型的语句的话,要用下面这个方法:
try? dbCon?.execute("PRAGMA foreign_key = ON;")
函数的参数就写你要执行的SQL语句就可以了。
    还有一种情况是希望得到返回值的,比如说查询语句等等,这个时候就要用下面这个方法:
let result = try? dbCon?.prepare("SELECT * FROM tb1;")
它会得到查询语句的返回值,至于这个返回值怎么时候,请参考后面关于数据查询部分的内容。

4.建立表格

    建立表格的时候,需要对每一个数据项的属性来进行指定,比如说主键,外键,默认值等等,在介绍这些之前,我们需要先认识一个数据类型:
Expression<T>
这是后面经常要用到的一个数据类型,它用来表示表的一个数据项,当然也可以表示某一条记录的某一个数据项,T为该属性的类型,如果指定了一个可选类型,那么表示该数据项可以为NULL,否则不可以为NULL,这里支持的类型和SQLite中类型的对应关系如下:

swiftSQLiteIntINTEGERDoubleREALStringTEXTnilNULL这里要注意的是,Int对应的是INTEGER而不是INT,因此如果你的主键是Int类型的话,是默认被设置为自增型的。
    比如说我要表示一个名为“name”的数据项,它是String类型的,我就应该写成:
Expression<String>("name")
    下一个要介绍的类型是Expressible,这是一个结构体,实现还是比较复杂的,但是我们基本上可以理解成Expression<Any>,所以如果要见到这个类型,就知道是要传入Expression的一个实例就好了。
    接下来是TableBuilder类型,本质也比较复杂,不过可以理解成[Expressible]就可以了,这个类型并不常用,只是在建表的时候用得到。
    终于说到建表了,建表的方法如下:
try? dbCon?.run(Table("test").create(ifNotExists: true, block:{(tb) in            tb.column(Expression<String>("name"))            tb.column(Expression<String?>("note"))        }))
Table是一个结构体,传入字符串作为表的名称,create方法有很多重载,这里的第一个参数如果为true,就表示如果该表已经存在就无视该动作,如果为false可以省略,这时如果表已存在就会抛出异常(由于本文主要是说明数据库的使用,这里所有的异常都没有理睬,所以用了try?语法,真实开发时应该给予考虑),第二个参数是一个(TableBuilder) -> ()类型的闭包,在闭包中对表格的每一个数据项进行设置,column方法也有很多重载,常用的有以下几个:
public func column<V : Value>(_ name: Expression<V>, unique: Bool = false, check: Expression<Bool>? = nil, defaultValue: Expression<V>? = nil)public func column<V : Value>(_ name: Expression<V>, primaryKey: Bool, check: Expression<Bool>? = nil, defaultValue: Expression<V>? = nil)
可以用来制定UNIQUE,CHECK,DEFAULT,PRIMARY KEY属性,与直接使用SQLite数据库相同,不再赘述。在次强调,NOT NULL属性是默认添加的,如果不想添加该属性,需要在Expression的类型中设置可选类型

4.1复合主键

     如果表中有复合主键,则不能再使用上面的方法,需要使用下面的方法:
tb.primaryKey(Expression<String>("name"), Expression<String>("property"))
调用primaryKey方法,传入若干个Expression,就可以把它们设置成复合主键。

4.2外键

    外键的设置需要制定本表中个一个属性,还要制定参照表和参照表中的属性,例如:
tb.foreignKey(Expression<String>("username"), references: Table("user"), Expression<String>("username"), update: .cascade, delete: .cascade)
    相当于如下的SQL语句:
FOREIGN KEY(username) REFERENCES user(username) ON UPDATE cascade ON DELETE cascade;
最后两个参数如果去掉的话,有外键约束的数据记录将不允许更改或删除。
    如果是复合外键,只需要把第一个参数和第三个参数改成Expression组成的元组就可以了,比如说:
tb.foreignKey((Expression<String>("forDevice"), Expression<String>("type")), references: Table("device"),( Expression<String>("name"), Expression<String>("property")), update: .cascade, delete: .cascade)
道理与单个的外键相同。
    这里还有一个要强调的地方(这其实是SQLite数据库的特点而不是sqlite.swift库的特点,但是经常容易碰到所以强调一下)就是,如果外键约束设置错误的话,在建表的时候是不会抛出异常的,而在插入数据的时候回有外键设置异常的报错,很多人在insert的时候发现了报错就以为一定是insert语句的问题,这并不一定,因为有可能是建表时就有的错误,但是它只会在操作数据记录的时候才会报错(不知道为什么这样设计,很坑)。一个比较常见的外键绑定错误就是,外键在参照表中必须是UNIQUE属性,也就是说,它要么有UNIQUE属性修饰,要么是主键。而如果它仅仅是复合主键中的一部分,并且没有UNIQUE修饰的话,是不能成为参照的外键的(这点超级超级超级坑),因为它不是主键的全部,所以是可以有重复的。如果你希望参照的属性是复合主键的话,那你就必须用复合外键参照整个复合主键才可以。总之就是,一定要确定它是不是唯一的,如果不是唯一属性的,不可以被参照。

5.插入记录

    先介绍一个类型,Setter类型,实现比较复杂,简化以后就是如下的一个结构
Expression<T> <- T

显示一个Expression,然后一个小于号和一个减号,也就是个向左的箭头,右边是一个对应类型的表达式,比如说下面这就是合法的表达式:

Expression<Int>("id") <- 1Expression<String>("name") <- "admin"
insert方法要求的参数就是一个Setter类型,用法如下:
try? dbCon?.run(Table("user").insert(Expression<String>("name") <- "admin"))
insert方法还可传入多个Setter,往后继续写就可以插入多个数据项:
try? dbCon?.run(Table("user").insert(Expression<String>("name") <- "admin"), Expression<Int>("id") <- 5)
不过就是要注意如果是非空属性的话,必须得一次性写全才可以,不能分多个insert语句插入

6.查询记录

    查询记录要用到的类型是Expression<Bool>类型,它可以通过两个同属性的Expression<T>运算获得,或者是一个Expression和一个常数获得,比如说

Expression<Int>("value") >= 5
就会返回一个Expression<Bool>类型的数据,所以选择一个表的某些复合条件的行,用到filter函数,传入的参数是一个Expression<Bool>类型的数据,例如:

let tb = Table("user").filter(Expression<Int>("id") >= 5)
相当于SQL语句:

SELECT * FROM user WHERE id >= 5;
如果选列的话,要用到select 函数,传入一个或若干个Expression,比如说:

let result = Table("user").select(Expression<String>("name"))
相当于SQL语句:
SELECT name FROM user;
当然,上面两个语句可以叠加使用,比如:

let result = Table("user").select(Expression<String>("name")).filter(Expression<Int>("id") > 8)
相当于SQL语句:

SELECT name FROM user WHERE id > 8;

    拿到的结果是一个AnySequence<Row>?类型的数据,这个类型比较讨厌,因为你不能通过下角标直接找到第几行第几行的数据,必须用遍历语句来查找,而且还是一个可选类型,要注意判断是否为空然后解包,遍历中得到的是一个Row类型的数据,可以通过get方法获得对应的数据,比如下面的例子:

for row in result! {    let name = row.get(Expression<String>("name"))    let id = row.get(Expression<Int>("id"))    Swift.print("name:" + name + "id:\(id)")}

7.更改记录

    更改记录其实就是查询和添加记录的组合,用到了update函数,不再过多说明,直接看例子:

dbCon?.run(Table("user").filter(Expression<Int>("id") > 5 && Expression<String>("sex") == "male").update(Expression<String>("name") <- "haha"))
相当于SQL语句:
UPDATE user SET name = "haha" WHERE id > 5 and sex = "male";

8.删除记录

    删除记录用法与更改记录相同,用到了selete函数,例如:

dbCon?.run(Table("user").fiilter(Expression("id") < 6).delete())
相当于SQL语句:

DELETE FROM user WHERE id < 6;

9.其他功能

    其实这些用法都与SQL语句非常的相似,所以用起来也很得心应手,drop函数用于删除表,alter函数用于更改表结构,等等的功能,只需要稍微看一下函数声明,一定就会用了。

    关于sqlite.swift的简单介绍就到这里,如果你有问题或者好的简介,非常欢迎在下面留言,我们共同来探讨,共同学习和进步。







原创粉丝点击