RelatedDB 1.1.6

RelatedDB 1.1.6

Related Code 维护。



RelatedDB 1.1.6

  • By
  • Related Code

这是什么?

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])

您还可以使用 limitoffset 参数。

let users = User.fetchAll(db, limit: 10)

let users = User.fetchAll(db, "age > 40", limit: 5, offset: 10)

顺序执行,线程安全

数据库写入操作是顺序化的。这意味着,Insert、Update 和 Delete 操作将一个接一个地执行(由 RelatedDB 管理)。

Fetch 方法是线程安全的。这意味着您将按请求发起时的线程返回结果。

注意:您可以从任何线程发起读取和写入操作。

数据类型

RelatedDB可以管理以下数据类型:BoolInt8Int16Int32Int64IntFloatDoubleStringDateData

日期格式

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 - 版权所有