简体   繁体   English

如何将数据添加到新创建的 Room 数据库?

[英]How to add data to newly created Room database?

I've tried to import data in the onCreate method:我尝试在 onCreate 方法中导入数据:

    db = Room.databaseBuilder(applicationContext,
            AppDatabase::class.java,
            "my-database")
        .allowMainThreadQueries()
        //.fallbackToDestructiveMigration()
        .addCallback(object: RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                Log.d("RoomDatabase.Callback", "onCreate called")
                importData()
            }
        })
        .build()

but that leads to a但这会导致

IllegalStateException: getDatabase called recursively IllegalStateException:递归调用 getDatabase

Doing the import after the database creation also doesn't work:在创建数据库后进行导入也不起作用:

    var performInitialImport = false

    db = Room.databaseBuilder(applicationContext,
            AppDatabase::class.java,
            "my-database")
        .allowMainThreadQueries()
        //.fallbackToDestructiveMigration()
        .addCallback(object: RoomDatabase.Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                Log.d("RoomDatabase.Callback", "onCreate called")
                performInitialImport = true
            }
        })
        .build()

    Log.d("PerformInitialImport", "$performInitialImport")

    if (performInitialImport) {
        importData()
    }

because the Callback isn't executed before Control Flow continues after the database was built.因为在数据库建立后控制流继续之前回调没有被执行。 This is evident by the fact that这从以下事实可以看出

D/PerformInitialImport: false D/PerformInitialImport:假

comes before来之前

D/RoomDatabase.Callback: onCreate called D/RoomDatabase.Callback: onCreate 调用

in the App's Run log.在应用程序的运行日志中。

I'm lost.我迷路了。 How am I meant to import data into the database upon first creation?我如何在首次创建时将数据导入数据库?

Update: The importData method uses the AppDatabase instance created on the first line.更新: importData方法使用在第一行创建的AppDatabase实例。 The db parameter passed to onCreate is the underlying low level database.传递给onCreatedb参数是底层的低级数据库。 Naturally, I want to use the DAOs and the Entities I already have to fill the database...自然,我想使用 DAO 和我已经拥有的实体来填充数据库......

The reason why you are getting the behaviour is that the build does not open the database and it's not until you use the database that it is opened and then if the database doesn't exist it will then be created and onCreate is called.你得到这种行为的原因是构建没有打开数据库,直到你使用数据库才打开它,然后如果数据库不存在,它将被创建并调用 onCreate。

As such performInitialImport will always be false unless you access the database, forcing it to be opened.因此performInitialImport将始终为false ,除非您访问数据库,强制打开它。

You need to open (access) the database before doing the test.在进行测试之前,您需要打开(访问)数据库。

Example:-例子:-

class MainActivity : AppCompatActivity() {

    var firstrun = false
    var myTableDao :MyTableDao? = null


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Log.d("ROOMBUILD","Building Room Database")
        val db = Room.databaseBuilder(this,AppDatabase::class.java,"mydb")
            .allowMainThreadQueries()
            .addCallback(object: RoomDatabase.Callback()
            {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    Log.d("ONCREATE","onCreate called.")
                    super.onCreate(db)
                    firstrun = true;
                }
            }
            )
            .build()
        Log.d("ROOMBUILD","Room database built")
        myTableDao = db!!.myTableDao()
        //myTableDao!!.getAll() //would also work assuming getAll is defined in the Dao
        db.openHelper.writableDatabase //<<<<<<<<<< Force open
        if (firstrun) {
            importData()
        }
         for (m in myTableDao!!.getAll()) {
             Log.d("MYTABLEINFO","Names is " + m.name + " ID is " + m.id)
         }
    }

    fun importData() {
        Log.d("IMPORTING","Data being imported")
        var mytable = MyTable()
        mytable.name = "MyData"
        myTableDao?.insert(mytable)
    }
}

Results结果

When installed:-安装时:-

 2019-11-08 10:36:18.629 D/ROOMBUILD: Building Room Database 2019-11-08 10:36:18.642 D/ROOMBUILD: Room database built 2019-11-08 10:36:18.664 D/ONCREATE: onCreate called. 2019-11-08 10:36:18.669 D/IMPORTING: Data being imported 2019-11-08 10:36:18.675 D/MYTABLEINFO: Names is MyData ID is 1

Subsequent runs:-随后的运行:-

 2019-11-08 10:37:07.759 D/ROOMBUILD: Building Room Database 2019-11-08 10:37:07.772 D/ROOMBUILD: Room database built 2019-11-08 10:37:07.789 D/MYTABLEINFO: Names is MyData ID is 1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM