Kotlin Multiplatform数据库实战:以SpotiFlyer为例,SQLDelight如何一份查询全端通用

发布时间:2026/9/19 17:50:38
Kotlin Multiplatform数据库实战:以SpotiFlyer为例,SQLDelight如何一份查询全端通用 Kotlin Multiplatform数据库实战以SpotiFlyer为例SQLDelight如何一份查询全端通用【免费下载链接】SpotiFlyerKotlin Multiplatform Music Downloader, Supports Spotify / Gaana / Youtube Music / Jio Saavn / SoundCloud.项目地址: https://gitcode.com/gh_mirrors/sp/SpotiFlyerSpotiFlyer 是一个 Kotlin Multiplatform 音乐下载器支持从 Spotify、Gaana、YouTube Music、Jio Saavn、SoundCloud 等平台解析并下载歌曲。这类多端应用Android、桌面、Web、iOS最大的痛点之一就是本地数据库每个平台都有各自的存储 API难道要为每端重写一遍建表和查询逻辑吗SpotiFlyer 的答案是SQLDelight——用一份 SQL 文件定义表结构与查询再由 Kotlin 的多平台机制expect/actual适配各端驱动实现一份查询全端通用。为什么多平台应用需要 SQLDelight在多平台项目中数据库代码通常有三种命运各端各写一套Android 用 Room、桌面用 JDBC、iOS 用 SQLite.swift……维护成本随平台数线性增长。只在一端做持久化换端后数据丢失用户体验割裂。一份 SQL 全端复用表结构、查询语句只写一次各平台只负责换驱动。SpotiFlyer 选择了第三种。SQLDelight 的核心思想是把 SQL 写成独立的.sq文件Gradle 插件在编译期解析这些文件生成类型安全的 Kotlin 代码——参数拼错、字段写错在编译期就会报错而不是运行时才崩。上手第一步Gradle 接入 SQLDelight 插件数据库逻辑集中在 common/database 模块中。配置非常简单核心只有三步应用com.squareup.sqldelight插件并声明数据库名与包名在commonMain依赖 runtime 与协程扩展所有平台共享在各平台 sourceSet 中引入对应的驱动依赖。相关配置可参考 common/database/build.gradle.ktsplugins { id(com.squareup.sqldelight) } sqldelight { database(Database) { packageName com.shabinder.database } }各平台的驱动依赖也清晰可见androidMain用android-driverdesktopMain用sqlite-driver JDBCiosMain用native-driver。所有版本号统一收敛在 buildSrc/deps.versions.toml 中管理避免版本漂移。一份 .sq 文件定义全部表结构与查询SQLDelight 最优雅的地方在于SQL 不是写在 Kotlin 字符串里而是放在 commonMain/sqldelight 目录下的.sq文件中。SpotiFlyer 有两张表下载记录表DownloadRecordDatabase.sqCREATE TABLE IF NOT EXISTS DownloadRecord ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, type TEXT NOT NULL, name TEXT NOT NULL, link TEXT NOT NULL UNIQUE ON CONFLICT REPLACE, coverUrl TEXT NOT NULL, totalFiles INTEGER NOT NULL DEFAULT 1 ); select: SELECT * FROM DownloadRecord WHERE link :link; add: INSERT OR REPLACE INTO DownloadRecord (type, name, link, coverUrl, totalFiles) VALUES (?,?,?,?,?);Token 表TokenDB.sq 用于持久化 Spotify 认证信息避免每次启动都重新走 OAuth 授权流程。注意:前缀的参数如:link——SQLDelight 会据此生成类型化的查询方法编译期就能检查参数个数与类型。这份文件放在commonMain里意味着Android、桌面、Web、iOS 生成的查询代码完全一致。各平台的 actual 实现同一份查询四种驱动既然 SQL 只写一份各平台要做的就只剩一件事提供一个驱动。SpotiFlyer 用 expect/actual 机制优雅地完成了这件事。在公共代码中声明 Expect.ktexpect fun databaseModule(): Module然后每个平台提供 actual 实现差异只有几行平台驱动关键实现AndroidAndroidSqliteDriverActualAndroid.kt桌面JVMJdbcSqliteDriverActualDesktop.ktWeb无null占位ActualJs.ktiOSnative-driverActualIos.kt以桌面端为例数据库文件会被放在用户主目录下的SpotiFlyer/Database中通过 JDBC 连接val driver JdbcSqliteDriver(url jdbc:sqlite:${databasePath.absolutePath})一个值得学习的细节Web 端没有本地 SQLite 环境actual 实现直接返回SpotiFlyerDatabase(null)占位保证编译通过且业务层无需特判逻辑的复杂性。统一封装业务层如何调用数据库各平台构造出Database实例后SpotiFlyer 用一个轻量的包装类 SpotiFlyerDatabase 持有它业务代码只需要依赖这个包装类完全不感知底层驱动差异。整个模块通过Koin 依赖注入装配databaseModule()在 ApplicationInit.kt 初始化时统一注册。于是无论是下载队列的去重查询selectby link、Token 的存取还是清空历史clear业务层调用的都是同一套生成代码。小结这份方案能直接抄走吗SpotiFlyer 的数据库架构是一个非常干净的最小实践核心就四条SQL 与 Kotlin 分离表结构和查询写在commonMain/sqldelight下的.sq文件编译期生成类型安全代码expect/actual 只切换驱动公共逻辑声明一次各平台 actual 实现仅几行代码版本统一收敛所有 SQLDelight 依赖通过 deps.versions.toml 统一管理优雅降级不支持本地存储的平台如 Web用null占位实现让公共代码保持无感知。如果你的 Kotlin Multiplatform 项目需要跨端持久化这套SQLDelight expect/actual 驱动切换的组合拳基本可以直接照搬。更多项目结构可以参考 settings.gradle.kts 中的模块划分以及各 provider 实现所在的 common/providers 模块。【免费下载链接】SpotiFlyerKotlin Multiplatform Music Downloader, Supports Spotify / Gaana / Youtube Music / Jio Saavn / SoundCloud.项目地址: https://gitcode.com/gh_mirrors/sp/SpotiFlyer创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询