如何在使用Room时手动调用CREATE TABLE?

时间:2018-01-23 23:36:12

标签: android kotlin database-migration create-table android-room

在Java中给出这个自定义SQLiteOpenHelper

public class ExamplesOpenHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "app.db";

    private static final String CREATE_TABLE_STATEMENT =
            "CREATE TABLE examples (_id INTEGER PRIMARY KEY, NAME TEXT);";

    public ExamplesOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_TABLE_STATEMENT);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS examples");
        onCreate(db);
    }
}

我可以在数据库迁移中引用CREATE_TABLE_STATEMENTonUpgrade()而不复制SQL代码。

我想对KotlinRoom执行相同的操作,如下所示:

@Database(
        entities = [
            (Example::class)
        ],
        version = 2
)
abstract class ExamplesDatabase : RoomDatabase() {

    companion object {

        const val NAME = "examples"

        @Volatile
        private var INSTANCE: ExamplesDatabase? = null

        @JvmStatic
        fun getInstance(context: Context): ExamplesDatabase =
                INSTANCE ?: synchronized(this) {
                    INSTANCE ?: buildDatabase(context).also {
                        INSTANCE = it
                    }
                }

        private fun buildDatabase(context: Context) =
                Room.databaseBuilder(
                        context.applicationContext,
                        ExamplesDatabase::class.java,
                        NAME)
                        .addMigrations(MIGRATION_1_2)
                        .build()

        private val MIGRATION_1_2 = object : Migration(1, 2) {
            override fun migrate(db: SupportSQLiteDatabase) {
                // How to invoke CREATE TABLE here?
            }
        }

    }

}

这次实际的表定义来自Example模型。如何从房间推断CREATE_TABLE_STATEMENT,以便我可以在迁移中使用它?我想避免编写语句手动,从而定义两次:一次在模型中,一次在SQL语句中。

2 个答案:

答案 0 :(得分:0)

不,我认为没有办法做到这一点。请参阅official tutorial

static final Migration MIGRATION_1_2 = new Migration(1, 2) {
    @Override
    public void migrate(SupportSQLiteDatabase database) {
        database.execSQL("CREATE TABLE `Fruit` (`id` INTEGER, "
                + "`name` TEXT, PRIMARY KEY(`id`))");
    }
};

似乎你必须自己写。

答案 1 :(得分:0)

您可以从类" ExamplesDatabase_Impl.java"中找到create table SQL,没有CREATE_TABLE_STATEMENT定义,只有硬代码。