迁移以将新数据行插入 Room DB

2024-01-01

我正在制作一个新版本的应用程序,其新功能需要 Room DB 中的设置表中包含更多行数据。尽管我的数据库在结构上没有改变(没有新表,没有列更改等),但我正在考虑在 Room DB 上运行新的迁移(DB v2 -> v3),只是为了将这些新数据行添加到现有表中。这太过分了吗?

DB_INSTANCE = Room.databaseBuilder(context.getApplicationContext(),
                            MyDatabase.class, Constants.DB_NAME)
                            .addMigrations(new Migration_1_2(context, 1, 2), new Migration_2_3(2, 3))
                            .build();

我知道我可以在 RoomDatabase 的 onCreate() / onOpen() 回调中添加数据。例如。

private static RoomDatabase.Callback rdc = new RoomDatabase.Callback() {
            public void onCreate (SupportSQLiteDatabase db) {
                // do something after database has been created
            }
            public void onOpen (SupportSQLiteDatabase db) {
                // do something every time database is open
            }
        };

但我不确定这两个是否合适?

onCreate() - 对于现有应用程序用户,不会调用此方法,因为他们已经拥有上一个应用程序版本的数据库。

onOpen() - 每次启动应用程序时都会运行 - 这看起来开销很大。

至少对于新的迁移来说,这只会为用户运行一次。这是正确的方法吗?


我确信现在您一定已经找到了解决方案,我将把这个问题留在这里给任何有同样问题的人。

简单的答案是肯定的,您走在正确的道路上。另一种选择是创建一个布尔首选项,并在用户更新应用程序并插入新行后分配相反的值。这意味着您必须编写代码来访问数据库、执行 CRUD 操作以及编辑共享首选项值。

如果您打算插入几行,请使用迁移方法来避免编写太多代码,否则请使用第二种方法。这是我的一个业余项目的示例。

static final Migration MIGRATION_4_5 = new Migration(4, 5) {
    @Override
    public void migrate(@NonNull SupportSQLiteDatabase database) {


        database.execSQL("INSERT INTO categories (id,type, name, amount, description) "
                + "SELECT NULL, 'expense', 'food', 0, NULL "
                + "UNION ALL SELECT NULL, 'expense', 'transportation', 0, NULL ");

    }
};

我在数据库创建中添加了回调,以确保安装当前版本的任何用户也拥有新数据

      private static AppDatabase buildDatabase(final Context appContext,
                                         final AppExecutors executors) {
    return Room.databaseBuilder(appContext, AppDatabase.class, DATABASE_NAME)
            .addCallback(new Callback() {
                @Override
                public void onCreate(@NonNull SupportSQLiteDatabase db) {
                    super.onCreate(db);
                    executors.diskIO().execute(new Runnable() {
                        @Override
                        public void run() {

                            // Generate the data for pre-population
                            AppDatabase database = AppDatabase.getInstance(appContext, executors);

                            List<Category> categories = DataGenerator.generateExpenseCategories();

                           insertData(database, categories);


                        }
                    });
                }
            })

       .addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4, MIGRATION_4_5)

            .build();
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

迁移以将新数据行插入 Room DB 的相关文章

  • Android Toast 消息不起作用

    我正在通过 Andengine 为 Android 开发游戏 我有 MainActivity 类和 GameScene 类 我在 GameActivity 中使用 Toast 消息 它正在发挥作用 Toast makeText this H
  • 无法获取 ConfigBean 中实体的正确 ID - Java EE

    我正在构建一个药房管理应用程序 每个药房都需要一名管理员 约束是这样的 public class Pharmacy implements Serializable Id GeneratedValue strategy GenerationT
  • Android 位置 API:获取提供商状态

    在 Android 中获取位置提供商状态的最佳方式是什么 当注册 LocationListener 以进行位置更新时 onStatusChanged String provider int status Bundle extras 每当状态
  • Android 软键盘 - 禁用某些键

    我正在寻找一种使用内置软键盘并禁用某些键的方法 例如 如果用户不应该使用字母 f 因为在列表中该字母不存在 则该键应显示为灰色 想象一下 用户可以在文本框中键入文本以从列表中进行选择 该列表包含 ABC BCCD 床 如果用户输入 A 然后
  • Android:将声音保存为铃声/SQLiteConstraintException

    我正在尝试使用 Android 将声音保存为铃声this http www stealthcopter com blog 2010 01 android saving a sound file to sd from resource and
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • 为什么我的地图视图上的叠加层没有显示?

    我按照 google hellomapview 教程中的说明进行操作 我得到了一个工作地图视图等 但是添加到地图中的两个项目没有显示 它们似乎在某个地方 因为点击指定位置会显示添加到项目中的消息 Edit 这是我的源代码 应该和google
  • 如果未安装应用程序,深层链接将重定向到 Play 商店

    我在我的应用程序中使用深度链接的概念 我真正想要的是 当我共享我的应用程序中的链接时 它工作正常 它会转到我想在我的应用程序中打开的活动 但问题是当用户没有这个时应用程序此链接通过手机浏览器打开 显示错误 未找到 但如果未安装应用程序 我想
  • RecyclerView 单击将数据传递到新活动

    我正在制作一个包含三个选项卡的应用程序 每个选项卡都有一个带有两个文本的 recyclerview 我希望用户能够单击任何 recyclerview 项目 并且该项目中的文本应传递到新活动 这是应用程序外观的图像 https i stack
  • 绘制平滑曲线

    我想创建更平滑的曲线 而不仅仅是线角 这是我现在画的图 这是我的代码 case FREEHAND float pts float ptk ptk new float 2 imageMatrix invert inv if mCurrentS
  • 膨胀类 android.support.design.widget.NavigationView 时出错

    我按照 NavigationView 的教程进行操作 但无法解决此错误消息 Error inflating class android support design widget NavigationView 教程链接 https www
  • eglCodecCommon:setVertexArrayObject:设置vao调试消息

    我的 Android Emulator API 28 logcat 被这样的消息搞得晕头转向 D eglCodecCommon setVertexArrayObject set vao to 1 1 0 0 D eglCodecCommon
  • Firebase 身份验证中是否需要 SMS Retriever API 才能进行 otp 自动填充?

    我在用Firebase auth api验证用户电话号码 目前 就我而言 我有一个屏幕 用户在其中输入电话号码 并在第二个屏幕上输入密码 根据文档firebase大多数时候自动检索 OTP 并启动验证过程 所以我的问题是它已经实现了SMS
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • 错误膨胀类 android.support.design.widget.NavigationView [启动时崩溃]

    该应用程序应该有一个导航抽屉 可以从左侧拉出并显示各种活动 但是一旦将导航栏添加到 XML Activity homescreen 文档中 应用程序一启动就会崩溃 主屏幕 java package com t99sdevelopment c
  • Google Wallet for Digital Goods API 与 Google Play 应用内结算

    想知道 Google 电子钱包结算 API 和 Google Play 应用内结算之间有什么区别 与 Google 电子钱包结算 API 相比 使用 GooglePlay 应用内购买结算服务有何优势 我看到 Wallet API 也支持 A
  • 如何在移动应用程序上连接到服务器?

    我是移动应用程序的新手 我基本上来自网络开发平台 我只是在玩 App Framework LungoJS Jquery Mobile kendo 等移动框架 以获得该垂直领域的一些知识 我正在开发的应用程序仍然处于 UI 级别 我所需要的只
  • 在数据库中存储类型时的最大 MIMEType 长度

    人们在数据库中使用什么作为 MIMEType 字段的长度 到目前为止我们看到的最长的是 72 字节 application vnd openxmlformats officedocument wordprocessingml documen
  • Android:是否可以在可绘制选择器中使用字符串/枚举?

    问题 Q1 有人设法让自定义字符串 枚举属性在 xml 选择器中工作吗 我通过以下 1 获得了一个布尔属性 但不是字符串属性 编辑 感谢您的回答 目前 android 仅支持布尔选择器 原因请参阅已接受的答案 我计划实现一个复杂的自定义按钮
  • 永久删除Android文件

    我发现了一个名为这会从 Android 设备中永久删除文件和文件夹 以便删除的文件无法再恢复 这是我正在谈论的应用程序 但我想知道如何做到这一点 我知道它是用 android studio 制作的 i尝试了常规的删除方式file delet

随机推荐