android Room DB中具有不同实体的多个数据库

dzhpxtsq  于 2023-03-06  发布在  Android
关注(0)|答案(1)|浏览(287)

我在我的Android应用程序中使用ROOM db。我在运行时创建多个DB,但我面临着为这些运行时数据库维护不同表的困难。在ROOM db中可以做到这一点吗?

abstract class AppDatabase : RoomDatabase() {

    companion object {
        private var mInstance: AppDatabase? = null

        @Synchronized
        fun getInstance(dbName: String): AppDatabase {
            if (mInstance == null)
                mInstance = Room.databaseBuilder(
                    OrbiApp.instance.applicationContext, AppDatabase::class.java,
                    dbName
                )
                    .fallbackToDestructiveMigration()
                    .addCallback(roomCallback)
                    .build()

            return mInstance!!

        }
} ```
qij5mzcb

qij5mzcb1#

是否可以在ROOM db中执行此操作?
是的,但是使用单个@Database注解类,就像您所做的那样,那么如果表是*不同的***,那么您将需要包括@Database注解所定义的实体列表中的所有表,以便无论预期的数据库是什么,都可以访问不同的**表。
您还遇到了单个示例的问题,因此如果在后续调用中使用getInstance,即使数据库名称不同,它也只会返回第一个数据库。
例如,如果您有:-

@Entity
data class T1(
    @PrimaryKey
    val id: Long?=null,
    val name: String
)
@Entity
data class T2(
    @PrimaryKey
    val id: Long?=null,
    val description: String
)
@Dao
interface AllDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(t1: T1): Long
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(t2: T2)

    fun insert(valueToInsert: String, dbName: String ) {
        when (dbName) {
            "DB1" -> insert(T1(name = valueToInsert))
            "DB2" -> insert(T2(description = valueToInsert))
        }
    }
}
@Database(entities = [T1::class,T2::class], exportSchema = false, version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun getAllDao(): AllDao

    companion object {
        private var mInstance: AppDatabase? = null
        @Synchronized
        fun getInstance(context: Context, dbName: String): AppDatabase {
            if (mInstance == null)
                mInstance = Room.databaseBuilder(
                    context, AppDatabase::class.java,
                    dbName
                )
                    .fallbackToDestructiveMigration()
                    .allowMainThreadQueries() /* For brevity of demo */
                    .addCallback(roomCallback)
                    .build()
            return mInstance!!
        }
        
        val roomCallback= object: Callback(){
        }
    }
}

沿着:

class MainActivity : AppCompatActivity() {
    lateinit var db1: AppDatabase
    lateinit var db2: AppDatabase
    lateinit var daoDB1: AllDao
    lateinit var daoDB2: AllDao
    val db1Name = "DB1"
    val db2Name = "DB2"
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        db1 = AppDatabase.getInstance(this,db1Name)
        db2 = AppDatabase.getInstance(this,db2Name)
        daoDB1 = db1.getAllDao()
        daoDB2 = db2.getAllDao()

        daoDB1.insert("value for T1 in DB1",db1Name)
        daoDB2.insert("value for T2 in DB2",db2Name)
    }
}

结果将是一个数据库DB 1,但在尝试获取时,DB2的示例返回DB 1,行插入到***不同的***表中。例如

也许这就是您遇到问题的地方。您需要区分示例。
为了进一步演示,请考虑以下内容(对getInstance函数的更改+新的buildDB函数):

@Database(entities = [T1::class,T2::class], exportSchema = false, version = 1)
abstract class AppDatabase : RoomDatabase() {
    abstract fun getAllDao(): AllDao

    companion object {
        private var mInstanceDB1: AppDatabase?=null
        private var mInstanceDB2: AppDatabase?=null
        @Synchronized
        fun getInstance(context: Context, dbName: String): AppDatabase {
            if (dbName == "DB1") {
                if (mInstanceDB1==null) {
                    mInstanceDB1 = buildDB(context,dbName)
                }
                return mInstanceDB1 as AppDatabase
            } else {
                if (mInstanceDB2==null) {
                    mInstanceDB2 = buildDB(context,dbName)
                }
                return mInstanceDB2 as AppDatabase
            }
        }
        private fun buildDB(context: Context, dbName: String): AppDatabase {
            return Room.databaseBuilder(context,AppDatabase::class.java,dbName)
                .allowMainThreadQueries().addCallback(roomCallback).build()
        }

        val roomCallback= object: Callback(){
        }
    }
}

在没有任何其他变更的情况下,重新运行应用程序,然后:-
对于DB 1:-

  • 保留预先存在的行,向T1添加1行(这次不是2行)
  • 可以看到DB2的存在

对于DB2:-

相关问题