与sqlite比较
本质:sqlite。SwiftSqlite是swift的封装。类似FMDB是OC的封装。
易于使用原因:sql语句转化为对应关于对象操作。其实对应的是相应的sql语句。
使用
初始化
- 数据库,表,表结构,初始化
public static let standard = PTDownloadTable()
//数据库
private var db: Connection?
//表
private let downLoadFile = Table("downLoadFile")
// 列(数据库表结构)
private let id = Expression<Int64>("id")
private let fielUrl = Expression<String>("fielUrl")
private let downLoadState = Expression<String>("downLoadState")
private let isBrowse = Expression<Bool>("isBrowse")
private let destinationFielUrl = Expression<String>("destinationFielUrl")
private let downLoadTime = Expression<String>("downLoadTime")
private let type = Expression<String>("type")
private let title = Expression<String>("title")
private let brief = Expression<String>("biref")
init () {
//
self.db = createDB()
createTable()
}
复制代码
- 创建数据库并连接
/// 创建数据库,并连接
private func createDB() -> Connection? {
//获取doc路径
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
//如果不存在的话,创建一个名为db.sqlite3的数据库,并且连接数据库
do {
let db = try Connection("\(path)/db.sqlite3")
print("✅数据库创建并连接成功:\(db)")
return db
} catch {
print("?数据库创建并连接失败:\(error)")
return nil
}
}
复制代码
- 创建表
/// 创建下载表,已经存在不会再次创建
private func createTable() {
if let db = self.db {
do {
try db.run(downLoadFile.create(block: { (t) in
t.column(id, primaryKey: .autoincrement)
t.column(fielUrl, defaultValue: "")
t.column(downLoadState, defaultValue: "0")
t.column(isBrowse, defaultValue: false)
t.column(destinationFielUrl, defaultValue: "")
t.column(downLoadTime, defaultValue: "")
t.column(type, defaultValue: "")
t.column(title, defaultValue: "")
t.column(brief, defaultValue: "")
}))
print("✅下载列表创建成功")
} catch {
print("?下载列表创建失败:\(error)")
}
}
}
复制代码
注意: 第一次创建成功,之后不会再次创建。
增
/// 增加记录
public func insertOne(_ fileModel: PTDownLoadModel) {
if let db = self.db {
let insertDownLoadModel = downLoadFile.insert(fielUrl <- fileModel.fielUrl,
downLoadState <- fileModel.downLoadState,
isBrowse <- fileModel.isBrowse,
destinationFielUrl <- fileModel.destinationFielUrl,
downLoadTime <- fileModel.downLoadTime)
do {
try db.run(insertDownLoadModel)
print("✅增加成功")
} catch {
print("?增加失败:\(error)")
}
}
}
复制代码
查
/// 查询多条记录
public func queryManyRecord() -> [PTDownLoadModel]? {
var array: [PTDownLoadModel] = []
if let db = self.db {
do {
for fileModel in try db.prepare(downLoadFile) {
let downLoadModel = PTDownLoadModel()
downLoadModel.fielUrl = fileModel[fielUrl]
downLoadModel.downLoadState = fileModel[downLoadState]
downLoadModel.isBrowse = fileModel[isBrowse]
downLoadModel.destinationFielUrl = fileModel[destinationFielUrl]
downLoadModel.downLoadTime = fileModel[downLoadTime]
downLoadModel.type = fileModel[type]
downLoadModel.title = fileModel[title]
downLoadModel.brief = fileModel[brief]
array.append(downLoadModel)
}
print("✅查询多条数据成功")
return array
} catch {
print("?查询多条数据失败:\(error)")
return nil
}
}
return nil
}
复制代码
/// 查询单条记录
public func queryOneRecord(_ url: String) -> Bool {
if let db = self.db {
do {
for fileModel in try db.prepare(downLoadFile) {
if url == fileModel[fielUrl] {
print("✅查询单条数据成功:\(url)")
return true
}
}
print("?查询单条数据失败")
return false
} catch {
print("?查询单条数据失败:\(error)")
return false
}
}
return false
}
复制代码
改
///更新单条条记录:下载状态和下载地址
public func updateOneLoadRecord(_ url: String,_ state: String,_ destinationUrl: String,_ loadTime: String,_ typeStr: String,_ titleStr: String,_ briefStr: String) {
if let db = self.db {
let fileModel = downLoadFile.filter(fielUrl == url)
do {
if destinationUrl == "" {
try db.run(fileModel.update(downLoadState <- state))
} else if loadTime == "" {
try db.run(fileModel.update(downLoadState <- state))
} else {
//只有真正下载完成,才更新:下载地址和下载时间
try db.run(fileModel.update(downLoadState <- state,
destinationFielUrl <- destinationUrl,
downLoadTime <- loadTime,
type <- typeStr,
title <- titleStr,
brief <- briefStr))
}
print("✅更新单条条记录(下载状态和下载地址)数据成功")
} catch {
print("?更新单条条记录(下载状态和下载地址):数据失败:\(error)")
}
}
}
复制代码
删
/// 删除对应数据
func delete(_ url: String) {
if let db = self.db {
let fileModel = downLoadFile.filter(fielUrl == url)
do {
try db.run(fileModel.delete())
print("✅删除成功:\(url)")
} catch {
print("?删除失败:\(url):\(error)")
}
}
}
复制代码
表字段更新
/// 更新表
private func updateTableColumn() {
if let db = self.db {
do {
try db.run(downLoadFile.addColumn(userId, defaultValue: ""))
print("✅下载列表更新成功")
} catch {
print("?下载列表更新失败:\(error)")
}
}
}
复制代码
一般表字段更新会伴随兼容之前版本问题。就需要考虑数据迁移。
数据迁移
/// 数据迁移(一开始没有userId列数据,更新值)
public func dataMigration(_ userIdStr: String) {
if let db = self.db {
let fileModel = downLoadFile.filter(userId == "")
do {
try db.run(fileModel.update(userId <- userIdStr))
UserDefaults.standard.setValue(true, forKey: "isMigration")
print("✅数据迁移成功")
} catch {
UserDefaults.standard.setValue(false, forKey: "isMigration")
print("?数据迁移失败:\(error)")
}
}
}
复制代码
需要把新增列userId的数据过滤出来,然后统一更新。迁移只需一次,所有用了userdefault记录。
/// 是否迁移成功
public func isMigrationSuccess() -> Bool {
if let isMigration = UserDefaults.standard.value(forKey: "isMigration") as? Bool {
return isMigration
} else {
return false
}
}
复制代码
判断迁移成功,就不必在迁移。
测试
- 使用模拟器测试,可以在电脑端看到具体路径。把db的路径打印出来就可以。
- 测试工具:【Navicat for SQLite】,打开文件即可。
- 数据更新可以刷新工具,数据同步。
多表查询
- 这些可以从下边官方文档看
- 实例教程(增删查改)Swift 3