会议室数据库强制创建回调

2022-09-04 06:30:03

我正在开发一个使用RoomDatabase的应用程序,该应用程序需要预先填充其数据;我已经设法通过添加回调来做到这一点,但是只有在第一次访问数据库时才会调用它(例如调用其中一个Daos函数)。onCreate()

有没有办法在不执行任何读取或写入操作的情况下强制创建数据库?

这是我的代码,被调用MyDatabase.get()App.onCreate()

@Database(entities = {Entity1.class, Entity2.class}, version = 1, exportSchema = true)
public abstract class MyDatabase extends RoomDatabase {

    private static MyDatabase sInstance;

    public synchronized static TaxCodeDatabase get(Context context) {
        if (sInstance == null) {
            sInstance = buildDatabase(context);
        }
        return sInstance;
    }

    private static MyCodeDatabase buildDatabase(final Context context) {
        return Room.databaseBuilder(context,
                MyCodeDatabase.class,
                "my-database")
                .addCallback(new Callback() {
                    @Override
                    public void onCreate(@NonNull SupportSQLiteDatabase db) {
                        super.onCreate(db);
                        sInstance.preFillData(context);
                      });
                    }
                })
                .build();
    }

    public abstract Entity1Dao entity2Dao();

    public abstract Entity2Dao entity1Dao();

    /**
     * Populates the database with a series of initial data
     *
     * @param aContext
     */
    public void prePopulateData(Context aContext) {
        //Populate database here
    }

答案 1

我花了一段时间才明白为什么在数据库生成器上调用后,Room 数据库没有填充初始数据。.build()

至于我,迁移和回调仅在实际的读/写操作上触发,这真的很违反直觉。实际上,该问题是由 Room 使用的原因引起的,如文档中所述:class RoomOpenHelper

一个打开的帮助程序,它保存对配置的引用,直到打开数据库。

结果,配置和所有回调都存储在类的实例中,而Sqlite的,它实际上执行数据库迁移,而不是创建(在Java中加载惰性类)。RoomOpenHelperSQLiteOpenHelper

要克服此行为,应执行任何导致此原因的操作。我最终采用了以下方法:getWritableDatabase()

RoomDatabase db = Room.databaseBuilder(context,
            ...)
            .build();

  // and then
db.beginTransaction()
db.endTransaction()

  // or query a dummy select statement
db.query("select 1", null)

return db

之后,将创建数据库并使用初始数据填充数据库。


答案 2

有没有办法在不执行任何读取或写入操作的情况下强制创建数据库?

不,很抱歉。

但是,没有什么可以阻止您在调用 Room 之前将预填充的数据库复制到适当的位置。您需要确保预填充的数据库包含 Room 的元数据(例如,通过使用 Room 本身创建该数据库)。


推荐