RelatedDB 是一个轻量级的 Swift 封装,围绕 SQLite 构建。
CocoaPods 是 Swift 和 Objective-C Cocoa 项目的依赖管理工具。
要将 RelatedDB 库整合到您使用 CocoaPods 的 Xcode 项目中,请在您的 Podfile
文件中引用它,如下所示
pod 'RelatedDB'
Swift Package Manager 是一个用于管理 Swift 代码分发的工具。
一旦您配置了 Package.swift
清单文件,您可以继续将 RelatedDB 包含在同一文件的 dependencies 部分中。
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)
获取一个对象看起来像这样
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 命令。
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 - 保留所有权利