[Jetpack] Verwenden Sie Room Migration, um die Datenbank zu aktualisieren und die Schemadatei zu exportieren (Einführung in die Schemadatei | Schemadateikonfiguration generieren | Schemadateiprozess generieren)





1. Einführung in die Schemadatei



Um Room Migration zum Aktualisieren der Datenbank zu verwenden , müssen Sie eine Reihe von Migrationsmigrationsklassen entsprechend der aktuellen Datenbankversion und Zielversion schreiben und eine aktualisierte Schemadatei generieren, bei der es sich um eine Datei im JSON-Format handelt, die den folgenden Inhalt enthält:

  • Versionsinformationen: einschließlich aktueller Version und Zielversion;
  • Erstellen Sie eine Tabellenanweisung: einschließlich der Definition und Feldinformationen der neu hinzugefügten Tabelle;
  • Anweisung zum Löschen einer Tabelle: einschließlich des Namens der zu ;
  • Anweisung zum Ändern der Tabelle: einschließlich des Namens der zu und der Definitionsinformationen des zu ändernden Felds;
  • Anweisung zum Einfügen von Daten: Geben Sie den Namen der Tabelle an , in die Daten eingefügt werden müssen , und die einzufügenden Daten.
  • Anweisung zum Löschen von Daten: einschließlich des Namens der Tabelle , die Daten löschen muss und der Löschbedingungen;

Die Schemadatei ist eine Datei, die die Struktur der Room-Datenbank beschreibt . Mithilfe dieser Datei können die historischen Änderungsdatensätze der Datenbank leicht verstehen und Probleme beheben.

Die Schemadatei definiert die Struktur von Elementen wie Tabellen, Spalten und Indizes in der Datenbank und enthält SQL-Skripts zum Erstellen und Aktualisieren der Datenbank.


Verwenden Sie die Migration von Room, um die Datenbank zu aktualisieren. Die generierte Schemadatei erfolgt normalerweise über die Aufgabe „roomExportSchema“ im Gradle-Build-Skript, die die Schemadatei in das angegebene Verzeichnis exportiert, das im Build-Skript „build.gradle“ konfiguriert werden muss.





2. Generieren Sie die Schemadateikonfiguration



Wenn Sie die Room-Datenbank aktualisieren, können Sie das Room-Migrationstool verwenden, um eine Schemadatei zu generieren.

Wenn Sie die Schemadatei exportieren , müssen Sie den Parameter exportSchema = true in der @Database-Annotation der RoomDatabase-Implementierungsklasse festlegen .

@Database(entities = [Student::class], version = 3, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    
    

Im vorherigen Blog wurde der Parameter „exportSchema“ auf „false“ gesetzt und die Schemadatei wurde nicht exportiert;


Darüber hinaus ist es erforderlich, den Generierungsort der Schemadatei im Build-Skript build.gradle zu konfigurieren und Parameter auf der Ebene „android / defaultConfig / javaCompileOptions / annotationProcessorOptions“ zu konfigurieren."room.schemaLocation": "$projectDir/schemas".toString()

Die vollständige Konfigurationshierarchie ist wie folgt:

android {
    
    
    namespace 'kim.hsl.rvl'
    compileSdk 32

    defaultConfig {
    
    
        applicationId "kim.hsl.rvl"
        minSdk 21
        targetSdk 32

        javaCompileOptions {
    
    
            annotationProcessorOptions {
    
    
                // 指定 Room Migration 升级数据库导出的 Schema 文件位置
                arguments = ["room.schemaLocation": "$projectDir/schemas".toString()]
            }
        }
    }
}

projectDir ist das Stammverzeichnis des Modulmoduls, das generierte Schemaverzeichnis, und src, build, build.gradle sind Dateien auf derselben Ebene;





3. Der Prozess der Generierung der Schemadatei




1. Datenbankversion 1 – Führen Sie die Anwendung zum ersten Mal aus


Anwendung mit Datenbankversion 1, erste Ausführung,

        fun inst(context: Context): StudentDatabase {
    
    
            if (!::instance.isInitialized) {
    
    
                synchronized(StudentDatabase::class) {
    
    
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        //.addMigrations(MIGRATION_1_2)
                        //.addMigrations(MIGRATION_2_3)
                        //.fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }

Kommentieren Sie die neu hinzugefügten Felder in der Entity-Entitätsklasse aus.

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    /*@ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0*/

    /**
     * degree字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    /*@ColumnInfo(name = "degree", typeAffinity = ColumnInfo.INTEGER)
    var degree: Int = 0*/

Setzen Sie die Datenblockversion auf 1:

@Database(entities = [Student::class], version = 1, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    
    

Führen Sie die Anwendung zum ersten Mal aus, um die Schemadatei 1.json der Datenbankversion 1 zu generieren.

Der Speicherort, an dem die Schemadatei generiert wird, ist der Pfad „app/schemes/package name/1.json“.

{
    
    
  "formatVersion": 1,
  "database": {
    
    
    "version": 1,
    "identityHash": "acca4b709e6c8b9b88d8328be36b9032",
    "entities": [
      {
    
    
        "tableName": "student",
        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `age` INTEGER NOT NULL)",
        "fields": [
          {
    
    
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": false
          },
          {
    
    
            "fieldPath": "age",
            "columnName": "age",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
    
    
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'acca4b709e6c8b9b88d8328be36b9032')"
    ]
  }
}

Fügen Sie hier eine Bildbeschreibung ein


2. Aktualisieren Sie Datenbankversion 1 auf Datenbankversion 2 – führen Sie die Anwendung ein zweites Mal aus


Legen Sie zunächst die Felder in der Entity-Entitätsklasse fest und fügen Sie das Geschlechtsfeld basierend auf Datenbankversion 1 hinzu.

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0

Definieren Sie dann die Migrationsklasse „Migration“, die die Datenbankversion 1 auf die Datenbankversion 2 aktualisiert.

        /**
         * 数据库版本 1 升级到 版本 2 的迁移类实例对象
         */
        val MIGRATION_1_2: Migration = object : Migration(1, 2) {
    
    
            override fun migrate(database: SupportSQLiteDatabase) {
    
    
                Log.i("Room_StudentDatabase", "数据库版本 1 升级到 版本 2")
                database.execSQL("alter table student add column sex integer not null default 1")
            }
        }

Rufen Sie dann RoomDatabase.Builder#addMigrations auf, um die oben definierte Migrationsmigrationsklasse hinzuzufügen.

        fun inst(context: Context): StudentDatabase {
    
    
            if (!::instance.isInitialized) {
    
    
                synchronized(StudentDatabase::class) {
    
    
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        .addMigrations(MIGRATION_1_2)
                        //.addMigrations(MIGRATION_2_3)
                        //.fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }

Ändern Sie abschließend die Datenbankversion auf 2.

@Database(entities = [Student::class], version = 2, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    
    

Die generierte Schemadatei für das Upgrade von Datenbankversion 1 auf Datenbankversion 2 lautet wie folgt:

{
    
    
  "formatVersion": 1,
  "database": {
    
    
    "version": 2,
    "identityHash": "84fb235f8062b0a6b0c8d1a6d1035c4f",
    "entities": [
      {
    
    
        "tableName": "student",
        "createSql": "CREATE TABLE IF NOT EXISTS `${
      
      TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `age` INTEGER NOT NULL, `sex` INTEGER NOT NULL)",
        "fields": [
          {
    
    
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": false
          },
          {
    
    
            "fieldPath": "age",
            "columnName": "age",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "sex",
            "columnName": "sex",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
    
    
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '84fb235f8062b0a6b0c8d1a6d1035c4f')"
    ]
  }
}

Fügen Sie hier eine Bildbeschreibung ein


3. Aktualisieren Sie Datenbankversion 2 auf Datenbankversion 3 – führen Sie die Anwendung zum dritten Mal aus


Legen Sie zunächst die Felder in der Entity-Entitätsklasse fest und fügen Sie das Abschlussfeld basierend auf der Datenbankversion 2 hinzu.

    /**
     * 性别字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "sex", typeAffinity = ColumnInfo.INTEGER)
    var sex: Int = 0

    /**
     * degree字段
     * 数据库表中的列名为 sex
     * 数据库表中的类型为 INTEGER 文本类型
     */
    @ColumnInfo(name = "degree", typeAffinity = ColumnInfo.INTEGER)
    var degree: Int = 0

Definieren Sie dann die Migrationsklasse „Migration“, die die Datenbankversion 2 auf die Datenbankversion 3 aktualisiert.

        /**
         * 数据库版本 2 升级到 版本 3 的迁移类实例对象
         */
        val MIGRATION_2_3: Migration = object : Migration(2, 3) {
    
    
            override fun migrate(database: SupportSQLiteDatabase) {
    
    
                Log.i("Room_StudentDatabase", "数据库版本 2 升级到 版本 3")
                database.execSQL("alter table student add column degree integer not null default 1")
            }
        }

Rufen Sie dann RoomDatabase.Builder#addMigrations auf, um die oben definierte Migrationsmigrationsklasse hinzuzufügen.

        fun inst(context: Context): StudentDatabase {
    
    
            if (!::instance.isInitialized) {
    
    
                synchronized(StudentDatabase::class) {
    
    
                    // 创建数据库
                    instance = Room.databaseBuilder(
                        context.applicationContext,
                        StudentDatabase::class.java,
                        "student_database.db")
                        .addMigrations(MIGRATION_1_2)
                        .addMigrations(MIGRATION_2_3)
                        //.fallbackToDestructiveMigration()
                        .allowMainThreadQueries() // Room 原则上不允许在主线程操作数据库
                                                  // 如果要在主线程操作数据库需要调用该函数
                        .build()
                }
            }
            return instance;
        }

Ändern Sie abschließend die Datenbankversion auf 3.

@Database(entities = [Student::class], version = 2, exportSchema = true)
abstract class StudentDatabase: RoomDatabase() {
    
    

Die generierte Schemadatei für das Upgrade von Datenbankversion 2 auf Datenbankversion 3 lautet wie folgt:

{
    
    
  "formatVersion": 1,
  "database": {
    
    
    "version": 3,
    "identityHash": "d88859680a038f5155613d94de7888cc",
    "entities": [
      {
    
    
        "tableName": "student",
        "createSql": "CREATE TABLE IF NOT EXISTS `${
      
      TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT, `age` INTEGER NOT NULL, `sex` INTEGER NOT NULL, `degree` INTEGER NOT NULL)",
        "fields": [
          {
    
    
            "fieldPath": "id",
            "columnName": "id",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "name",
            "columnName": "name",
            "affinity": "TEXT",
            "notNull": false
          },
          {
    
    
            "fieldPath": "age",
            "columnName": "age",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "sex",
            "columnName": "sex",
            "affinity": "INTEGER",
            "notNull": true
          },
          {
    
    
            "fieldPath": "degree",
            "columnName": "degree",
            "affinity": "INTEGER",
            "notNull": true
          }
        ],
        "primaryKey": {
    
    
          "columnNames": [
            "id"
          ],
          "autoGenerate": true
        },
        "indices": [],
        "foreignKeys": []
      }
    ],
    "views": [],
    "setupQueries": [
      "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd88859680a038f5155613d94de7888cc')"
    ]
  }
}

Fügen Sie hier eine Bildbeschreibung ein

おすすめ

転載: blog.csdn.net/han1202012/article/details/131048359