如何在首次运行时填充Android Room数据库表?

use*_*289 32 android android-room

在我SQLiteOpenHelper有一个onCreate(SQLiteDatabase ...)方法,我用一些初始数据填充数据库表.

有没有办法在第一个应用程序运行时将一些数据插入Room数据库表?

Arn*_*Rao 85

您可以在创建数据库后运行脚本,也可以在每次打开数据库时运行脚本RoomDatabase.Callback,此类可在最新版本的Room库中使用.

您需要实现onCreateonOpen方法RoomDatabase.Callback并将其添加到RoomDatabase.Builder如下所示.

yourDatabase = Room.databaseBuilder(context, YourDatabase.class, "your db")
    .addCallback(rdc)
    .build();

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
    }
};
Run Code Online (Sandbox Code Playgroud)

参考

您可以在RoomDatabase.Callback方法中使用Room DAO来填充数据库.有关完整示例,请参阅分页和房间示例

   RoomDatabase.Callback dbCallback = new RoomDatabase.Callback() {
        public void onCreate(SupportSQLiteDatabase db) {
            Executors.newSingleThreadScheduledExecutor().execute(new Runnable() {
                @Override
                public void run() {
                   getYourDB(ctx).yourDAO().insertData(yourDataList);
                }
            });
        }
    };
Run Code Online (Sandbox Code Playgroud)

  • 应将此标记为正确答案.谢谢! (8认同)
  • 我遇到了一个问题,回调没有在`.build()`上触发.仅在第一次真正的读/写操作[如此处所述](/sf/ask/3379665901/#51139067) (5认同)

N12*_*234 13

我试图用RoomDatabase.Callback通过Arnav饶的建议,而是利用回调作为数据库已经建成之前创建的回调,你不能使用DAO.您可以使用db.insert和内容值,但我认为这不是正确的.所以在仔细研究之后 - 花了我很多年代大声笑 - 但我确实在查看谷歌提供的样本时找到了答案.

https://github.com/googlesamples/android-architecture-components/blob/master/PersistenceContentProviderSample/app/src/main/java/com/example/android/contentprovidersample/data/SampleDatabase.java

参见第52行和第71行的方法 - 在那里你可以看到在构建数据库实例之后,下一行调用一个方法来检查数据库中是否有任何记录(使用DAO),然后它是否为空插入初始数据(再次使用DAO).

希望这有助于其他被困的人:)

  • 非常感谢您的分享。这看起来像是正确的方法。 (2认同)

小智 7

您可以在创建数据库后填充表,确保操作在单独的线程上运行。您可以按照下面的课程在第一次预填充表格。

应用数据库.kt

@Database(entities = [User::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {

    abstract fun userDao(): UserDao

    companion object {

        // For Singleton instantiation
        @Volatile private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME)
                    .addCallback(object : RoomDatabase.Callback() {
                        override fun onCreate(db: SupportSQLiteDatabase) {
                            super.onCreate(db)
                            //pre-populate data
                            Executors.newSingleThreadExecutor().execute {
                                instance?.let {
                                    it.userDao().insertUsers(DataGenerator.getUsers())
                                }
                            }
                        }
                    })
                    .build()
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

数据生成器.kt

class DataGenerator {

    companion object {
        fun getUsers(): List<User>{
            return listOf(
                User(1, "Noman"),
                User(2, "Aayan"),
                User(3, "Tariqul")
            )
        }
    }

}
Run Code Online (Sandbox Code Playgroud)


Dar*_*und 5

我尝试了很多方法来做到这一点,每个方法都没有.

首先,我尝试使用'addMigrations'方法向Room添加Migration实现,但发现它只在数据库升级期间运行,而不是在创建时运行.

然后,我尝试使用'openHelperFactory'方法将SQLiteOpenHelper实现传递给Room.但是在创建了一堆类以便绕过Room的包级访问修饰符后,我放弃了努力.我也试过继承Room的FrameworkSQLiteOpenHelperFactory,但是,它的构造函数的包级访问修饰符也不支持这个.

最后,我创建了一个IntentService来填充数据,并从我的Application子类的onCreate方法调用它.该方法有效但更好的解决方案应该是本页其他地方Sinigami提到的跟踪器问题的即将到来的解决方案.

达里尔

[2017年7月19日添加]

该问题看起来好像已经在1.0.0室解决了.Alpha 5.此版本添加了对RoomDatabase的回调,允许您在首次创建数据库时执行代码.看一眼:

https://developer.android.com/reference/android/arch/persistence/room/RoomDatabase.Callback.html