sqldelight

大象笔记 > 标签 > sqldelight

Android SQLDelight (六) 查看 Android Room 创建的 SQLite 数据库建表语句

为了将一个 Android App 由 Room 迁移到 SQLDelight 方案,首先需要了解既有 app 的表结构。 使用 Android Studio 自带的 App Inspection 将 Room 创建的 SQLite 数据库导出为 db 文件, 如 item_database.db。 打开 db 文件 使用 sqlite3 命令连上数据库文件,查看具体表的建表语句 sqlite3 item_database.db 注意是 sqlite3,而不是 sqlite. 否则会报错: > sqlite item_database.db Unable to open databa ...

阅读全文...

Android SQLDelight (一) 配置及数据库初始化

SQLDelight 官方的文档有点简略,有些步骤看不懂,而网上找到的大部分文章都是跨平台的配置, 而我只想做 Android 单平台的,于是详细记录了一下配置过程。 app build.gradle 注意是 app 模块的 build.gradle, 而不是整个项目的 build.gradle. plugins { id "app.cash.sqldelight" version "2.0.0-alpha05" } sqldelight { databases { Database { // This will be the name ...

阅读全文...

Android SQLDelight (二) 向本地 SQLite 数据库插入数据

首先需要 在 Android 中配置好 SQLDelight 及数据库初始化,然后就可以测试写入数据了。 .sq 在 SQLDelight 的 sq 文件中补充用于插入的 SQL 语句: 一个用于插入 一个用于保存 save: INSERT OR REPLACE INTO items VALUES ?; insert: INSERT INTO items(name, num, notes) VALUES (?, ?, ?); 这里有个不好的习惯,就是表名用了复数,会导致生成的 kotlin data class 类名也是复数形式,影响代码可读性。 为了兼容旧版本的 app,所以没有改正 ...

阅读全文...

Android SQLDelight (三) 查询数据并借助 Flow 更新到 RecyclerView

周五晚上直到 11 点也没有调通 Android SQLDelight Flow 的用法,由于周六早上 5 点半就要起床去参加运动会,所以就此作罢。今天去体育场路途遥远,于是路上查了一堆文档,才理清了思路。晚上回来,终于调通。 build.gradle 配置 dependencies { implementation "app.cash.sqldelight:coroutines-extensions:2.0.0-alpha05" } RecyclerView 监听数据变化 lifecycleScope.launch(Dispatchers.IO) { (activ ...

阅读全文...

Android SQLDelight (四) Hilt 将 database 依赖注入 ViewModel

由于使用的 Navigation UI 会在 navigate 时销毁 fragment 的 View,实际操作时,由 list to detail to list 这样的浏览路径,会导致 fragment onViewCreated 中的逻辑执行多次。这是不合理的,所以需要将相关逻辑挪到 view model 中 (fragment view 销毁了,但是 fragment 没有销毁,所以 view model 是安全的)。而 view model 中不应该去获取 fragment 或 activity 的实例,也就没法拿到之前偷懒放到 activity 中的 SQLDeligth Data ...

阅读全文...

Android SQLDelight (五) 查询单条数据库记录,并更新 UI

之前用 Android SQLDelight 查询批量数据非常方便,没想到查询单条数据反而有点搞不清。 第一种做法 这样查询就是在主线程里,即 UI 线程。实际操作很快,没有任何卡顿。 val id = args.id if (id != 0L) { val item = viewModel.database.itemQueries.findOne(id).executeAsOne() binding.name.setText(item.name) binding.number.setText(item.num.toString()) } 第二种做法 val id = args.id ...

阅读全文...

Android Room 替代品 SQLDelight 中文入门教程

对于我这种非 Java 程序员,实在忍受不了 Room DAO 这种形式主义,所以找了一个 Android 上操作数据库的替代品方案,SQLDelight。 SQLDelight 只需要手写 SQL,自动生成 kotlin data class 代码,然后用起来跟 ORM 没啥区别,非常好用。每个 ORM 方案的学习成本都不低,还有很多坑。而用 raw sql 就没有这种烦恼了。当然 SQLDelight 还有跨平台的优势,虽然我目前用不上。我甚至都想将 golang 项目中的 Gorm 换成类似的方案。 于是在从 Room 迁移到 SQLDelight 的过程中,整理了这个系列的教程/笔记: ...

阅读全文...

Android SQLDelight (七) 从 Room 迁移的改造点

继续将原有的 Compose 项目重写为 XML View,本来不想折腾,心想要不直接沿用原来的 Room 代码,但是看了 DAO 和 Repository 这种风格的代码,还是忍不了。 既然没有退路了,就得保证对历史数据的兼容。 数据库名称 注意,用 SQLDelight 指定数据库名称时,不要加 .db 后缀。否则跟之前 Room 生成的文件名不一致。 - val driver: SqlDriver = AndroidSqliteDriver(Database.Schema, context, "item_database.db") + val driver: Sq ...

阅读全文...

保质期管理 app, 基于 SQLite 的过期时间排序

在基于 Android XML View 重写 Jetpack Compose 版保质期管理 app 时, 用 SQLDelight 替代了 Room 来做 SQLite 数据库管理。 但是在实现过期时间排序功能时,引入了一个 bug。 原来的数据库中的过期时间字段有两种值,NULL 或者时间对应的秒数。 现在又引入了零值。导致排序混乱。 正确的排序效果 在保质期管理 app 中,已过期的物品,或者快过期的应该排列在前面,而不会过期的应该排在后面,如图所示: 零值是否合理 例如录入一个物品时,可以不填写过期时间,那么数据库中应该存储 null 还是 0。 这里确实应该存储 NULL,而不是 ...

阅读全文...