这是什么?
RelatedDB 是一个围绕 SQLite 的轻量级 Swift 包装器。
要求
- iOS 13.0+
- Xcode 12.0+
- Swift 5.0+
安装
CocoaPods
CocoaPods 是 Swift 和 Objective-C Cocoa 项目的依赖项管理器。
要将 RelatedDB 库集成到您的 Xcode 项目中并利用 CocoaPods,请在下面的 Podfile
中引用它
pod 'RelatedDB'
Swift 包管理器
Swift 包管理器 是管理 Swift 代码分发的一种工具。
一旦您配置了 Package.swift
清单文件,您可以继续将 RelatedDB 包含在同一文件的依赖项部分。
dependencies: [ .package(url: "https://github.com/relatedcode/RelatedDB.git", from: "1.1.5") ]
手动
如果您不希望使用任何依赖项管理器,您可以将 RelatedDB 手动集成到项目中。只需将 RelatedDB/Sources
文件夹中的所有 *.swift
文件复制到您的 Xcode 项目中即可。
用法
连接到数据库
import RelatedDB
let db = RDatabase()
您也可以指定数据库文件名或完整路径。默认文件名为 database.sqlite
,默认路径为 Library/Application Support
。
let db = RDatabase(file: "db.sqlite")
let db = RDatabase(path: "yourpath/db.sqlite")
定义对象
RelatedDB 提供了一个协议,有助于将数据库行作为常规对象操作。
class User: NSObject, RDObject {
@objc var userId = 0
@objc var name = ""
@objc var age = 0
@objc var approved = false
class func primaryKey() -> String {
return "userId"
}
}
通过创建上述 User 类,RelatedDB 将自动为您创建以下 SQLite 表
CREATE TABLE IF NOT EXISTS User (userId INTEGER PRIMARY KEY NOT NULL, name TEXT, age INTEGER, approved INTEGER);
注意:由于 RDObject 类的所有属性名都将在 SQLite 命令中使用,请避免在类定义中使用 SQLite 关键字。
插入对象
使用上述 User 类创建对象将如下所示
let user = User()
user.userId = 1001
user.name = "John Smith"
user.age = 42
user.approved = false
user.insert(db)
更新对象
现有的对象可以被更新
user.age = 43
user.update(db)
插入与更新
如果您不确定对象是否已存在于数据库中,则可以继续使用以下方法
user.insertUpdate(db)
它将首先尝试执行 INSERT 命令,如果失败(静默),则执行 UPDATE 命令。
还可以使用以下方法
user.updateInsert(db)
它将首先尝试执行 UPDATE 命令,如果失败(静默),则执行 INSERT 命令。
删除对象
现有的对象可以被删除
user.delete(db)
获取对象(s)
获取单个对象将如下所示
let user = User.fetchOne(db, key: 1001)
可以通过以下方式获取多个对象
let users = User.fetchAll(db)
let users = User.fetchAll(db, "age > 40")
let users = User.fetchAll(db, "age = ?", [42])
let users = User.fetchAll(db, "age >= :min AND age <= :max", [":min": 18, ":max": 99])
您还可以使用 limit
和 offset
参数。
let users = User.fetchAll(db, limit: 10)
let users = User.fetchAll(db, "age > 40", limit: 5, offset: 10)
顺序执行,线程安全
数据库写入操作是顺序化的。这意味着,Insert、Update 和 Delete 操作将一个接一个地执行(由 RelatedDB 管理)。
Fetch 方法是线程安全的。这意味着您将按请求发起时的线程返回结果。
注意:您可以从任何线程发起读取和写入操作。
数据类型
RelatedDB可以管理以下数据类型:Bool
、Int8
、Int16
、Int32
、Int64
、Int
、Float
、Double
、String
、Date
、Data
。
日期格式
Date
值将以ISO格式化的String
存储在数据库中。默认格式是ISO 8601("1970-01-01T01:01:01.000Z"),由ISO8601DateFormatter
类生成。
您也可以通过以下方式指定自己的日期格式
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.timeZone = TimeZone(secondsFromGMT: 0)
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
RDDate.custom(formatter)
注意:您只需要在代码库中指定一次日期格式。实际上是在进行任何数据库操作之前。
值字典
虽然将数据库行作为对象管理是一种简单、优雅的方式,但您可能希望将数据作为Dictionary
管理。
插入 (使用字典)
将新对象作为字典插入
let values: [String: Any] = ["userId": 1001, "name": "John Smith", "age": 42, "approved": false]
db.insert("User", values)
更新 (使用字典)
将现有对象作为字典更新
let values: [String: Any] = ["userId": 1001, "age": 43]
db.update("User", values)
主键必须在值字典中包含。否则,不会发生任何操作。
获取结果 (作为字典)
获取一个对象作为字典
let user = db.fetchOne("User", key: 1001)
在这种情况下,结果类型将是[String: Any]
。
获取多个对象作为字典
let users = db.fetchAll("User")
let users = db.fetchAll("User", "age > 40")
let users = db.fetchAll("User", "age = ?", [42])
let users = db.fetchAll("User", "age >= :min AND age <= :max", [":min": 18, ":max": 99])
在上述情况下,结果类型将是[[String: Any]]
。
转换对象 (转换为字典)
将现有对象转换为字典
let values = user.values()
字典中的日期值
当使用值字典(插入或更新数据)时,日期值可以以Date
或ISO格式化的String
的形式放入字典中。
当以字典形式获取数据时,日期值将始终以ISO格式化的String
表示。
批量更新
您可以通过指定条件来更新多个对象。
let values = ["approved": true]
User.updateAll(db, values, "age >= ? AND age <= ?", [30, 35])
或者,通过指定主键值来更新一个对象。
let values = ["approved": true]
User.updateOne(db, values, key: 1001)
批量删除
您可以通过指定条件来删除多个对象。
User.deleteAll(db, "age >= ? AND age <= ?", [30, 35])
或者通过指定主键值来删除一个对象。
User.deleteOne(db, key: 1001)
对象计数
您可以通过指定条件来获取对象数量。
let count = User.count(db)
let count = User.count(db, "age > 40")
let count = User.count(db, "age >= ? AND age <= ?", [30, 35])
检查对象
您可以通过指定主键值来检查对象是否存在(或不存在)。
if (User.check(db, key: 1001)) {
// do something
}
或者通过指定条件来检查一组对象是否存在(或不存在)。
if (User.check(db, "age >= ? AND age <= ?", [30, 35])) {
// do something
}
创建观察者
为了在数据库更改时刷新用户界面,您可以使用数据库观察者。
检查User类所有可能的更改将包括
let types: [RDObserverType] = [.insert, .update, .delete]
let observerId = User.createObserver(db, types) { method, objectId in
// do something
}
但是,您可以使用条件来缩小更改数量的范围
let observerId = User.createObserver(db, types, "OBJ.age > 40") { method, objectId in
// do something
}
您还可以使用以下观察者类型来检查特定的数据库更改(单独或组合):.insert
、.update
、.delete
。
为了获取新用户的通知,但不包含更新和/或删除的用户
let observerId = User.createObserver(db, .insert) { method, objectId in
// do something
}
或者为了获取专门删除的用户的通知,将看起来像这样
let observerId = User.createObserver(db, .delete) { method, objectId in
// do something
}
移除观察者
一旦不再需要数据库观察者,您可以通过以下方式将其移除
User.removeObserver(db, observerId)
执行普通SQL
如果您需要,可以执行普通SQL命令。
db.execute("DELETE FROM User WHERE age = 42;")
删除表,创建表
虽然SQLite表是自动创建的,但您也可以手动DROP和/或CREATE表。
db.dropTable("User")
db.createTable("User")
在这些情况下,也需要先定义User
类。
清理数据库
如果您需要,可以使用以下方式销毁并重新 创建所有表
db.cleanupDatabase()
错误处理
关键问题将导致fatalError
,其他任何情况都会在Xcode输出窗口中报告。
您可以使用以下方式修改调试级别
RDDebug.level(.none)
RDDebug.level(.error)
RDDebug.level(.all)
限制
RelatedDB工具包处于初始发布阶段。它是功能性的,可以处理大多数工作负载。然而,目前一些功能尚未支持
- 数据库迁移
- 数据库加密
- 框架集成
© Related Code 2022 - 版权所有