android room migrations

要开启 

exportSchema = true

 

 

 

迁移测试

导入:room-testing

错误

androidx.test.ext 报错  Failed to resolve: androidx.test.ext:junit:1.3.0

去掉:androidx.test.ext 的版本号,version.ref = "junitVersion" ,由composeBom 决定版本

测试代码

import android.content.Context
import androidx.room.Room
import androidx.room.testing.MigrationTestHelper
import androidx.sqlite.db.framework.FrameworkSQLiteOpenHelperFactory
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistryimport com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.io.IOException

@RunWith(AndroidJUnit4::class)
class MigrationTest {

    private val TEST_DB = "migration-test"

    @get:Rule
    val helper: MigrationTestHelper = MigrationTestHelper(
        InstrumentationRegistry.getInstrumentation(),
//        MigrationDb::class.java.canonicalName,
        TestDatabase::class.java,
        listOf(),
        FrameworkSQLiteOpenHelperFactory()
    )



    @Test
    @Throws(IOException::class)
    fun migrate1To2() {

        var db = helper.createDatabase(TEST_DB, 2).apply {
            // Database has schema version 1. Insert some data using SQL queries.
            // You can't use DAO classes because they expect the latest schema.
             execSQL("INSERT INTO user (first_name,last_name)  VALUES('[email protected]', 'Philipp')");
             execSQL("INSERT INTO user (first_name,last_name)  VALUES('first_name', 'test')");
            val cursor = query("select * from user")
            while (cursor.moveToNext()){
                val id = cursor.getInt(0)
                val name = cursor.getString(1)
                val lastName = cursor.getString(2)
                println("id:$id,name;$name,lastName:$lastName")
            }
            println("ok")
            // Prepare for the next version.
            close()
        }
        println("ok-ok")

        db = helper.runMigrationsAndValidate(TEST_DB, 2, true)

        db.query("SELECT * FROM user").apply {
            assertThat(moveToFirst()).isTrue()
            println(moveToFirst())
            println(getLong(getColumnIndex("id")))
//            assertThat(getLong(getColumnIndex("id"))).isEqualTo(0)
        }

        // Re-open the database with version 2 and provide
        // MIGRATION_1_2 as the migration process.
//        db = helper.runMigrationsAndValidate(TEST_DB, 2, true, TestDatabase.MIGRATION_1_2)

        // MigrationTestHelper automatically verifies the schema changes,
        // but you need to validate that the data was migrated properly.
    }

    @Test
    fun testAllMigrations() {
        helper.createDatabase(TEST_DB, 1).apply { close() }

        Room.databaseBuilder(
            InstrumentationRegistry.getInstrumentation().targetContext,
            TestDatabase::class.java,
            TEST_DB
        ).addMigrations(TestDatabase.MIGRATION_3_4, TestDatabase.MIGRATION_4_5).build().apply {

            openHelper.writableDatabase.close()
        }
        println("testAllMigrations ok")
    }
}


@RunWith(AndroidJUnit4::class)
class SimpleEntityReadWriteTest {
    private lateinit var userDao: UserDao
    private lateinit var articleDao: ArticleDao
    private lateinit var db: TestDatabase

    @Before
    fun createDb() {
        val context = ApplicationProvider.getApplicationContext<Context>()
        db = Room.inMemoryDatabaseBuilder(
            context, TestDatabase::class.java).addMigrations(TestDatabase.MIGRATION_3_4, TestDatabase.MIGRATION_4_5).build()
        userDao = db.userDao()
        articleDao = db.articleDao()
//        userDao.getAll().forEach(::println)
    }

    @After
    @Throws(IOException::class)
    fun closeDb() {
        db.close()
    }

    @Test
    @Throws(Exception::class)
    fun writeUserAndReadInList() {
//        val user: User = TestUtil.createUser(3).apply {
//            setName("george")
//        }
        val user = User(null, "11", "44")
        userDao.insertAll(user)
        val userList = userDao.getAll()
        userList.forEach(::println)

        val article = Article(null,"hi","content1","test")
        val article2 = Article(null,"hi2","content1","test")
        articleDao.insertAll(article,article2)
        articleDao.getAll().forEach(::println)
//        assertThat(byName.get(0), equalTo(user))
    }
}

TestDatabase 代码

import androidx.room.AutoMigration
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase


@Database(entities = [User::class, Article::class, Fruit::class], version = 5, exportSchema = true, autoMigrations = [ AutoMigration(from = 1, to = 2), AutoMigration(from = 2, to = 3)])
abstract class TestDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
    abstract fun fruitDao(): FruitDao
    abstract fun articleDao(): ArticleDao

    companion object{
        val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, `name` TEXT, " +
                        "PRIMARY KEY(`id`))")
            }
        }
        val MIGRATION_3_4 = object : Migration(3, 4) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("CREATE TABLE IF NOT EXISTS `article` (`id` INTEGER, `title` TEXT, `content` TEXT," +
                        "PRIMARY KEY(`id`))")
            }
        }
        val MIGRATION_4_5 = object : Migration(4, 5) {
            override fun migrate(db: SupportSQLiteDatabase) {
                db.execSQL("alter table article add column author text")
            }
        }
    }

}

  参考文档:https://developer.android.com/training/data-storage/room/migrating-db-versions#kotlin_1

 

posted on 2026-01-02 17:58  少杨  阅读(4)  评论(0)    收藏  举报