GRDB.swift 数据库迁移指南:从 GRDB 4 升级到 GRDB 5
前言
GRDB.swift 是一个强大的 Swift 数据库工具库,随着版本 5 的发布,它带来了许多重要的改进和变化。本文将全面解析从 GRDB 4 迁移到 GRDB 5 的关键步骤和注意事项,帮助开发者顺利完成升级。
升级准备
在开始迁移前,建议先完成以下准备工作:
- 确保当前使用的是 GRDB 4 的最新版本
- 修复所有已弃用的警告
- 预留足够时间处理数据库观察相关的改动(这是本次升级中变化最大的部分)
新版本要求
GRDB 5 提高了最低系统要求:
- Swift 5.3+(之前是 4.2+)
- Xcode 12.0+(之前是 10.0+)
- iOS 11.0+(之前是 9.0+)
- macOS 10.10+(之前是 10.9+)
- tvOS 9.0+(不变)
- watchOS 2.0+(不变)
数据库配置变化
数据库配置方式有了显著改变,现在更集中地使用 Configuration.prepareDatabase(_:) 方法:
// 旧版(GRDB 4)
var config = Configuration()
config.trace = { ... } // SQL语句追踪
config.prepareDatabase = { db in // 准备数据库
... // 自定义设置
}
let dbQueue = try DatabaseQueue(path: dbPath, configuration: config)
dbQueue.add(function: ...) // 添加自定义函数
dbQueue.add(collation: ...) // 添加自定义排序规则
dbQueue.add(tokenizer: ...) // 添加自定义FTS5分词器
// 新版(GRDB 5)
var config = Configuration()
config.prepareDatabase { db in // 使用新方法集中配置
db.trace { ... }
db.add(function: ...)
db.add(collation: ...)
db.add(tokenizer: ...)
...
}
let dbQueue = try DatabaseQueue(dbPath, configuration: config)
ValueObservation 的重大变化
ValueObservation 是 GRDB 中用于观察数据库值变化的工具,在 GRDB 5 中经历了重大重构。这些变化使得 GRDB 原生 API、Combine 发布器和 RxGRDB 提供了统一的接口和行为,消除了之前版本中存在的细微差异。
创建观察对象
在 GRDB 5 中,创建 ValueObservation 的方式更加统一:
// 新版标准方式
let observation = ValueObservation.tracking { db in
/* 获取并返回观察值 */
}
// 示例:观察所有玩家
let observation = ValueObservation.tracking { db in
try Player.fetchAll(db)
}
// 简写形式
let observation = ValueObservation.tracking(Player.fetchAll)
旧版中的多个专用方法已被移除,统一使用上述方式。
启动观察
启动观察的方式也有变化:
start方法现在返回 DatabaseCancellable 对象,可以显式停止观察onError处理程序现在是必需的
// 新版启动方式
let cancellable = observation.start(
in: dbQueue,
onError: { error in ... },
onChange: { value in print("新值: \(value)") })
// 停止观察
cancellable.cancel()
运行时行为变化
ValueObservation 的行为有以下重要变化:
- 初始值通知:现在默认在主线程异步通知初始值。如果需要同步获取初始值,需使用
.immediate调度选项:
observation.start(
in: dbQueue,
scheduling: .immediate, // 同步获取初始值
onError: { error in ... },
onChange: { [weak self] players in
self?.updateView(players)
})
// 此处视图已更新
-
通知合并:现在可能会合并多个事务的变更通知。如需每个事务都收到通知,请使用 DatabaseRegionObservation。
-
重复值过滤:不再自动过滤重复值。如需此功能,请使用
removeDuplicates操作符。 -
数据库连接关闭:不再阻止数据库连接关闭。当连接关闭时,观察将停止发送新值。
-
错误处理:发生错误后观察将终止,不再重启。
Combine 集成变化
GRDB 4 的 Combine 支持是通过单独的 GRDBCombine 库实现的,现在已直接集成到 GRDB 5 中。主要变化是移除了 fetchOnSubscription() 方法,改用 scheduling: .immediate 实现相同效果。
其他重要变化
-
SQL 追踪:
Configuration.trace属性已移除,改用Database.trace(options:_:)方法。 -
批量更新:
<-操作符已移除,改用set(to:)方法:
// 新版批量更新
try Player.updateAll(db, Column("score").set(to: 0))
-
SQL 插值:子查询不再自动添加括号,需要手动添加。
-
自定义函数:现在支持可调用值语法:
// 新版调用方式
Player.select(myFunction(Column("name")))
- 模块导入:自定义 SQLite 构建现在使用
GRDB模块名,不再需要单独导入 SQLite 底层库。
迁移建议
- 先处理所有编译错误,利用 Xcode 提供的自动修复建议
- 重点测试数据库观察相关功能
- 注意初始值加载方式的变化对 UI 的影响
- 考虑是否需要将部分 ValueObservation 替换为 DatabaseRegionObservation
- 检查所有 Combine 和 RxGRDB 相关的代码
结语
GRDB 5 通过统一 API 和行为,提供了更加一致和可靠的数据库操作体验。虽然迁移过程可能需要一些调整,但这些变化为应用带来了更好的性能和可维护性。建议开发者仔细测试数据库相关的所有功能,确保迁移后的行为符合预期。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



