Wie ArrayList speichern von Enum in RoomDatabase

meine Frage ist, wie speichern

List<Enum>

in RoomDatabase,
bisher finde ich keine Antwort.

  • Ich würde vorschlagen, den Zusatz „android-Zimmer“ als ein tag zu Ihrer Frage.
  • Ich konnte es nicht finden, bevor ;), danke
  • Ich habe meine Antwort auf die Frage, ob es das problem lösen? Falls nicht, bitte kommentieren, was Sie brauchen.
InformationsquelleAutor murt | 2017-06-22



5 Replies
  1. 5

    Enum:

    public enum HelloEnum {
        A,
        B,
        C
    }

    Konverter:

    public class EnumConverter {
    
        @TypeConverter
        public List<HelloEnum> storedStringToEnum(String value) {
            List<String> dbValues = Arrays.asList(value.split("\\s*,\\s*"));
            List<HelloEnum> enums = new ArrayList<>();
    
            for (String s: dbValues)
                enums.add(HelloEnum.valueOf(s));
    
            return enums;
        }
    
        @TypeConverter
        public String languagesToStoredString(List<HelloEnum> cl) {
            String value = "";
    
            for (HelloEnum lang : cl)
                value += lang.name() + ",";
    
            return value;
        }    
    }

    In Bezug auf das einfügen und abrufen Ihrer Daten, funktioniert dies nicht, Fragen zu stellen.

    @Dao
    public interface HelloPojoDao {
    
        @Query("SELECT * FROM helloPojo")
        List<HelloPojo> fetchAll();
    
        @Insert
        void insertPojo(HelloPojo pojo);
    }

    Ich würde jedoch darauf hin, dass eine Filterung mit enum wird ein wenig komplizierter jetzt. Zum Beispiel, wenn Sie möchten, schreiben Sie eine Abfrage zum abrufen von Objekten mit enum.Ein und enum.B, Sie haben eine Abfrage zu erstellen, die Abfragen, die ein string-Objekt für Sie. In diesem Fall „SELECT * FROM pojo, WO enums enthält ‚A‘ und ‚B‘. Als solche ist es besser, die Nummern zuweisen Werte der Enumerationen (wie @Kuffs Antwort details), wie die Parsen von Ganzzahlen wird wahrscheinlich produzieren weniger Probleme als Parsen von strings.

    Hoffe, dass dies Ihr Problem löst. Fühlen Sie sich frei, Fragen in den Kommentar-Abschnitt, und happy hunting!

  2. 5

    Ok mit Kotlin ist viel einfacher, als mit name

    class EnumTypeConverter {
    
        @TypeConverter
        fun restoreEnum(enumName: String): EnumType = EnumType.valueOf(enumName)
    
        @TypeConverter
        fun saveEnumToString(enumType: EnumType) = enumType.name
    }
  3. 1

    Lassen Sie mich die Art und Weise des Bleibens/abrufen es mit kotlin.

    Welche Einschränkungen haben wir während der operation?

    • Wir speichern enum-Liste als string-Feld in der Datenbank, so können wir nicht effizient auswählen oder Suche in der Datenbank basiert auf es
    • Wir serialisieren jeder enum-Wert zu string und Deserialisieren es wieder
    • wir können nicht Basis das Verhalten auf ordinale Feld um zu verhindern, dass Fehler durch die Verlängerung der enum in der Zukunft, also müssen wir ein konstantes Feld, das stellt jeden enum-Wert
      • wir können nicht die Basis auf Standard – toString Methode der Liste zu einem string, da es möglicherweise abhängen, die Umwelt, in der wir genau verwenden

    So die ordnungsgemäße Umsetzung meiner Meinung nach Aussehen wird:

    1. Erstellen Enumerable – Schnittstelle, die alle enum-Klassen die persistenten db implementieren sollte
    2. Jede enum-Klasse sollte Methode zur Erstellung mit übergebenen serialisierten parameter, die wiederhergestellt enum-Wert
    3. Erstellen kotlin-Erweiterung zu serialisieren/Deserialisieren Liste der Enumerationen, die
    4. Create type-Konverter für jede Art von enum

    So, die Enumerable-Schnittstelle:

    /** marks the enum with custom int code for each value */
    interface Enumerable {
        val code: Int
    }

    enum-Beispiel:

    enum class PaymentSystemEntity constructor(
        override val code: Int
    ) : Enumerable {
        VISA(1),
        MASTERCARD(2),
        UNKNOWN(0);
    
        companion object {
            fun parseFromCode(code: Int): PaymentSystemEntity = values()
                .firstOrNull { it.code == code } ?: UNKNOWN
        }
    
    }

    Serialisierung Erweiterungen:

    fun <T> List<T>.asString(): String where T : Enum<T>, T : Enumerable = this
        .map { it.code }
        .joinToString(separator = ",")
    
    fun <T> String.toEnumList(creator: (code: Int) -> T): List<T> where T : Enum<T>, T : Enumerable = this
        .split(',')
        .map { it.toInt() }
        .map { creator(it) }

    Sample-Typ Konverter enum:

    class PaymentSystemTypeConverter {
    
        @TypeConverter
        fun paymentSystemsToString(value: List<@JvmSuppressWildcards PaymentSystemEntity>): String =
             value.asString()
    
        @TypeConverter
        fun stringToPaymentSystems(value: String): List<@JvmSuppressWildcards PaymentSystemEntity> =
            value.toEnumList { PaymentSystemEntity.parseFromCode(it) }
    
    }

    Können Sie andere Arten von Sammlungen umgesetzt in einer gleichen Weise

  4. 0

    Serialise Ihre Enumerationen, die in Ganzzahlen und speichern diese stattdessen.

    Beim abrufen der Werte, führen Sie die umkehroperation durch.

    Beide Vorgänge sind erklärt in meiner Antwort auf diese Frage:

    Wie passend int enum

    • Ok, ich denke besser zu speichern als String „1“ , „2“, … und so weiter, damit ich speichern kann mehr als eine enum – guter Punkt. Es erfordert boilerplate… hym ist es erforderlichen?
    • String oder int. Spielt eigentlich keine Rolle. Das Konzept ist das gleiche.
  5. 0

    Jack Dalton version in Kotlin:

    @TypeConverter
    fun storedStringListLineType(value: String): List<LineType> {
        val dbValues = value.split("\\s*,\\s*".toRegex()).dropLastWhile { it.isEmpty() }
        val enums: MutableList<LineType> = ArrayList()
    
        for (s in dbValues)
            enums.add(LineType.valueOf(s))
        return enums
    }
    
    @TypeConverter
    fun listLineTypeToStoredString(listLineTypes: List<LineType>): String {
        var value = ""
    
        for (lineType in listLineTypes)
            value += lineType.name + ","
    
        return value
    }

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.