在Objective-C中,用于数据持久化的方法有以下几种:
- 使用plist文件
- 使用preference 保存数据
- NSKeyArchiver 归档
- Sqlite3
- CoreData
在日常开发中,虽然经常需要储存某些用户的个人信息之类的,这样我们用的更多的是plst和preference,但是对于大批量的数据,比如说TableView中的Data数据进行处理,还是需要数据库来进行处理。
CoreData是基于Sqlite的封装,但是貌似被黑的很惨,这里就暂时不用了。而且因为我自己尝试使用过CoreData,感觉使用的话,不仅仅需要用到图形界面,还要编写代码。对于我这个纯代码党来说,感觉有点复杂。希望苹果公司将来能够对其进行不断改良吧。
而在移动端我们最最常用的还是Sqlite,在OC中,我们有耳熟能详的FMDB,但是在Swift中,我们能使用什么呢?在通过网上搜索了一段时间之后。SQLite.swift映入了我眼帘(我才不会说因为Realm的文档太复杂而不去看他了呢!)
#安装方法
对于使用cocoapods的我来说,第三方库的安装其实相对而言十分简单的。
- 只要在该工程下使用
vim podfile
创建对应的podfile文件- 输入对应的第三方库的名字和版本号:
pod 'SQLite.swift', '~> 0.10.1'
,由于是Swift我们这里还需要换行输入use_frameworks!
这样才能将对应的库导入到我们的工程中。
- 输入对应的第三方库的名字和版本号:
esc
后输入:wq
,保存文本内容- 输入
pod install
安装对应库就可以了
如果有小伙伴不知道怎么安装cocoapods,可以参照我的这篇文章来进行安装
#基本介绍
这个第三方框架有着自己详细的官方文档,各位可以点击进去自行查看。不过都是英文的,可能阅读起来有点麻烦。所以我在这简单的介绍下相关的内容。
#基本使用
##创建
对于数据库而言,主要的创建就是数据库的创建和表的创建
###数据库的创建
只要直接获取就可以,这个库会帮我们解决如果文件不存在的问题。
|
|
###表的创建
首先我们通过库中的Table
类来获取这个对象
|
|
然后我们创建我们需要在表中的放入的元素。
这里就需要介绍下
Sqlite中存在的值类型和类中的变量的对应情况了。
Swift Type | SQLite Type |
---|---|
Int64 | INTEGER |
Double | REAL |
String | TEXT |
nil | NULL |
SQLite.Blob | BLOB |
然后就是创建我们想要的元素对象了
let id = Column
let name = Column
其中创建的时候中<>中的值就是我们设置的元素,()中的内容就是元素名
在SQLite中的所有涉及到元素的增删改查的所有内容都是使用column对象来进行处理的。
而创建的话也十分简单
|
|
当然肯定有人会问很多问题
Q
:表如果已经存在了,那怎么办?元素的唯一性怎么办?主键怎么设置?……A:别急,听我慢慢道来。
这里框架里面已经给我们提供了很多可以遍历的方法
####解决表已经存在的问题
我们可以翻看他的源代码中的Table
类的创建函数create
方法,这个创建方法是这么写的
|
|
很明显他里面已经帮我们考虑了我们平常使用中的常用方法,其中temporary就是创建虚拟表(也就是存放在内存中,不存放在实际沙盒路径中的数据表),ifNotExists是判断是否已经存在对应的表文件。block是用来创建对应的TableBuilder
对象。
####解决元素的相关属性问题
在create的时候我们使用了闭包,这样就可以在每次执行的时候捕获对象,从而使得每次都能对表进行处理。通过查看他的源码,我们发现这里面的t实际上就是一个TableBuilder对象。我们可以用TableBuilder的column方法
|
|
当然我们不会直接调用这个方法,毕竟这个方法那么长,不符合Swift编码规范,所以我们可以使用作者已经缩略好的内容,从而方便使用,这里就粗略的介绍下对应变量:
- name:对应的Expression类型,也就是我们前面创建的Express<>()的变量
- Datetype:元素的类型,就是前面表格中的SwiftType,一般代码会帮我们自动设置好
- primaryKey:判断是否要设置为主键
- null:是否可以置为null,
- unique:是否键值唯一
- check:判断对应的内容是否符合某种表解析,比如说:email.check(“%@%”),
- reference:添加引用
- collate:指定排序规则
- defaultValue:默认值
数据的增删改查
###增加
|
|
这个返回的是一个Int,即插入对应的行的行id
###删除
|
|
这个返回的是一个Int,即删除行的数目
那如果需要删除某一行,那就需要使用对应的筛选函数了(在查找中会提到)
###修改
|
|
这个返回的是一个Int,即修改行的数目
###查找
查找和上面的略有不同,因为我们查找,肯定是为了查找某一行的内容,或者说需要对内容进行排列,或者左右连接其他表等等。这个时候我们就需要使用其他的函数了。(因为框架里面没有select方法)
在框架中查找对应的是内容的QueryType的函数主要有这几个filter(筛选),join(表连接),group(group by),limit(对筛选条件进行约束),这几个函数与日常使用的SQL语句使用基本上一致,所以在这不过多解释。但是在使用filter的时候,如果判断值为某个值,那么需要用到column。所以在每次选择前,需要对需要用到的值创建对象。
但是由于选出的值需要进行展示,而且不同人的展示方式不同,比如说有的人要取和,有的人要输出。
除此之外,对于筛选的内容,框架的作者使用链式的方法,从而在编码的过程中更加方便,比如说下面这条语句,很明显让人一读就能力姐他到底是什么意思。
|
|
###数据转换
这个时候单纯的table是不够用了,作者就把方法写到了db里面。
- scalar:聚合,用来获得对应想要的数值,一般用于获得count,max,min,avg,sum,totle等
- prepare:获得所有元素值,然后使用for循环进行遍历(在for循环中,如果想要某个元素的值,你需要使用
let idNum = item[id]
id为column对象) - pluck:获得一行,如果是选取了所有,那么获得第一行
- run:用来执行delete,update,insert,create语句
- trace:每次执行sql语句都要执行这里面的内容。(
db.trace { print($0) }
在执行db的所有方法前,使用这句,会在每次执行的时候都输出sql语句) - excuse:直接执行SQL语句,为了方便写习惯了SQL语句的人。
##删除
删除表可以直接使用drop()
方法而删除某一标签,即dropIndex,则调用dropIndex
方法。
除此之外,之所以这个框架那么好用,他还重载了符号。比如说你需要写入某个column,你可以使用
<-
,这大大的方便了代码的可读性,从而提高了理解的效率。