Wie speichere ich das Aufzählungsfeld im Datenbankraum?

Lesezeit: 4 Minuten

Ich muss den Wert aus dem schreiben enum Aufzählung in die Datenbank. Beim Kompilieren tritt ein Fehler auf. Was mache ich falsch?

Kann nicht herausfinden, wie dieses Feld in der Datenbank gespeichert wird. Sie können erwägen, einen Typkonverter dafür hinzuzufügen.

@ColumnInfo(name = "state_of_health")
@TypeConverters(HealthConverter::class)
var health: Health

enum class Health(val value: Int){
    NONE(-1),
    VERY_BAD(0),
    ...
}

class HealthConverter{

    @TypeConverter
    fun fromHealth(value: Health): Int{
        return value.ordinal
    }

    @TypeConverter
    fun toHealth(value: Int): Health{
        return when(value){
            -1 -> Health.NONE
            0 -> Health.VERY_BAD
            ...
            else -> Health.EXCELLENT
        }
    }

}

  • Sieht so aus, als ob Sie Ihre kommentieren sollten Database Klasse mit @TypeConverters Anmerkung (und nicht Ihre enum class). Prüfen developer.android.com/training/data-storage/room/…

    – Halbgott

    2. August 2019 um 12:50 Uhr

  • @ Demigod ja, das funktioniert. Sie können eine Antwort schreiben

    – Gesehen

    2. August 2019 um 13:07 Uhr

Benutzeravatar von Allan Veloso
Allan Veloso

Sie können jede Aufzählung wie folgt konvertieren:

class Converters {

     @TypeConverter
     fun toHealth(value: String) = enumValueOf<Health>(value)

     @TypeConverter
     fun fromHealth(value: Health) = value.name
}

Oder wenn Sie es vorziehen, es als SQL zu speichern integerSie können auch ordinal verwenden:

class Converters {

    @TypeConverter
    fun toHealth(value: Int) = enumValues<Health>()[value]

    @TypeConverter
    fun fromHealth(value: Health) = value.ordinal
}

Leider gibt es keine Möglichkeit, Generika zu verwenden Enum<T> um dies zu erreichen, da ungebundene Generika einen Fehler auslösen Cannot use unbound generics in Type Converters.

Das Team von Android Room könnte ernsthaft eine Anmerkung und einen Generator für Enums zu ihrem Kapt-Compiler hinzufügen.

Kommentieren Sie schließlich eine Datenbankklasse, eine Entitätsklasse, eine Dao-Klasse, eine Dao-Methode, einen Dao-Methodenparameter oder eine Entitätsfeldklasse damit:

@TypeConverters(Converters::class)

  • Wie verwende ich die Aufzählung in der Datenklasse? Mit dem Wert oder Enum?

    – Raffael

    12. November 2020 um 15:50 Uhr

  • @Rafael Nachdem Sie den Typkonverter verwendet haben, können Sie enum direkt in Ihrer Entitätsklasse verwenden.

    – Sarthak_ssg5

    30. Oktober 2021 um 5:03 Uhr

In ist das kein Thema mehr Version 2.3.0-alpha4: “Room verwendet jetzt standardmäßig einen Enum-zu-String- und umgekehrt-Typkonverter, wenn keiner vorhanden ist. Wenn ein Typkonverter für eine Enum bereits vorhanden ist, wird Room die Verwendung dieses Typs gegenüber dem Standardtyp priorisieren.”

„Wenn für Enum bereits ein unidirektionaler Konverter zum Lesen vorhanden ist, verwendet Room möglicherweise versehentlich den integrierten String-to-Enum-Konverter, was möglicherweise nicht erwünscht ist. Dies ist ein bekanntes Problem und kann behoben werden, indem es zu einem bidirektionalen konvertiert wird Konverter.”

Benutzeravatar des Halbgottes
Halbgott

Um dies zu beheben, kommentieren Sie Ihre Database Klasse mit @TypeConverters Anmerkung (und nicht Ihre enum class).

Beispiel:

@Database(entities = arrayOf(User::class), version = 1)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao
}

Prüfen https://developer.android.com/training/data-storage/room/referencing-data

  • Gibt es einen anderen Weg? In JPA ist so viel einfacher.

    – Allan Veloso

    1. Februar 2020 um 16:50 Uhr

  • @AllanVeloso, was möchtest du als “anderen Weg” haben? Alternativ können Sie in Ihren Modellen Daten eines Basistyps speichern (z. B. enum ordinal as Intoder Aufzählungsname als String, usw.), aber wird es besser sein? Ich weiß auch nicht, was die JPA ist …

    – Halbgott

    3. Februar 2020 um 11:31 Uhr

  • JPA = Java-Persistenz-API. Es handhabt die Persistenz von Enum-Klassen mit einer einfachen Annotation @Enumerated(EnumType.STRING) oder @Enumerated(EnumType.ORDINAL) auf dem Feld. Auf diese Weise müssen Sie nicht für jede Aufzählung einen Konverter erstellen.

    – Allan Veloso

    3. Februar 2020 um 23:06 Uhr

  • @AllanVeloso, vielleicht hilft es, einer einzigen Schnittstelle durch alle Aufzählungen zu folgen. Ich habe meine Antwort ergänzt.

    – Halbgott

    4. Februar 2020 um 10:43 Uhr

  • Auch nicht gut, jedes Mal, wenn Sie eine Enum-Option definieren, müssen Sie die Methode getId() überschreiben. Ich habe versucht, Generika, Inline Retified und Generika zu verwenden. aber Raum unterstützt es auch nicht, Fehler Cannot use unbound generics in Type Converters. Konvertieren Sie es besser manuell.

    – Allan Veloso

    5. Februar 2020 um 15:16 Uhr

Enum-Klasse;

enum class Priority {
HIGH,
MEDIUM,
LOW
}

Konverterklasse;

class Converter {

@TypeConverter
fun fromPriority(priority: Priority): String {
    return priority.name
}

@TypeConverter
fun toPriority(priority: String): Priority {
    return Priority.valueOf(priority)
}

}

Verwendungszweck;

@Database(entities = [MyData::class], version = 1, exportSchema = false)
@TypeConverters(Converter::class)
abstract class MyDatabase : RoomDatabase() {

  // todo

}

Benutzeravatar von Zain
Zain

Für Java-Entwickler

Das Enum

public enum Health {
    NONE(-1),
    VERY_BAD(0);

    public final int value;

    Health(int newValue) {
        value = newValue;
    }

    public int getValue() {
        return value;
    }
}

Der Typkonverter

public class HealthConverter {

    /**
     * Convert Health to an integer
     */
    @TypeConverter
    public static int fromHealthToInt(Health value) {
        return value.ordinal();
    }

    /**
     * Convert an integer to Health
     */
    @TypeConverter
    public static Health fromIntToHealth(int value) {
        return (Health.values()[value]);
    }

}

Benutzeravatar von Waran-
Waran-

Seit Room Version 2.3.0 können Sie hier Enum Look speichern https://developer.android.com/jetpack/androidx/releases/room?hl=ru#version_230_3

1431730cookie-checkWie speichere ich das Aufzählungsfeld im Datenbankraum?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy