109 votes

Android Room Database: Comment gérer Arraylist dans une entité?

Je viens d'implémenter Room pour la sauvegarde des données hors ligne. Mais dans une classe d'entité, j'obtiens l'erreur suivante:

 Error:(27, 30) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
 

Et la classe est comme suit:

 @Entity(tableName = "firstPageData")
public class MainActivityData {
@PrimaryKey
private String userId;

@ColumnInfo(name = "item1_id")
private String itemOneId;

@ColumnInfo(name = "item2_id")
private String itemTwoId;

   // THIS IS CAUSING THE ERROR... BASICALLY IT ISN'T READING ARRAYS
   @ColumnInfo(name = "mylist_array")
    private ArrayList<MyListItems> myListItems;

public String getUserId() {
    return userId;
}

public void setUserId(String userId) {
    this.userId = userId;
}


public ArrayList<MyListItems> getMyListItems() {
    return myListItems;
}

public void setCheckListItems(ArrayList<MyListItems> myListItems) {
    this.myListItems = myListItems;
}
}
 

Donc, fondamentalement, je veux sauvegarder ArrayList dans la base de données mais je n’ai rien trouvé de pertinent. Pouvez-vous me guider sur la façon de sauvegarder un tableau en utilisant Room?

REMARQUE: la classe MyListItems Pojo contient 2 chaînes (à ce jour).

Merci d'avance.

129voto

Amit Bhandari Points 762

Les types de convertisseur sont conçus spécialement pour cela. Dans votre cas, vous pouvez utiliser l'extrait de code donné ci-dessous pour stocker des données dans une base de données.

 public class Converters {
@TypeConverter
public static ArrayList<String> fromString(String value) {
    Type listType = new TypeToken<ArrayList<String>>() {}.getType();
    return new Gson().fromJson(value, listType);
}

@TypeConverter
public static String fromArrayList(ArrayList<String> list) {
    Gson gson = new Gson();
    String json = gson.toJson(list);
    return json;
}
}
 

Et mentionnez cette classe dans votre Room DB comme ceci

 @Database (entities = {MainActivityData.class},version = 1)
@TypeConverters({Converters.class})
 

Plus d'infos ici

93voto

CommonsWare Points 402670

Option #1: Avez - MyListItems un @Entity, comme MainActivityData est. MyListItems un @ForeignKey de retour à l' MainActivityData. Dans ce cas, même si, MainActivityData ne peut pas avoir d' private ArrayList<MyListItems> myListItems, comme dans la Salle, les entités ne font pas référence à d'autres entités. Un modèle d'affichage ou similaire POJO construire pourrait avoir un MainActivityData et de ses associés ArrayList<MyListItems>, cependant.

Option #2: mettre en place une paire de @TypeConverter méthodes pour convertir ArrayList<MyListItems> à et de certains type de base (par exemple, un String, comme par exemple en utilisant JSON comme format de stockage). Maintenant, MainActivityData peut avoir son ArrayList<MyListItems> directement. Cependant, il n'y aura pas de table pour MyListItems, et si vous ne pouvez pas interroger sur MyListItems très bien.

66voto

Redman Points 4834

Version Kotlin pour le convertisseur de type:

  class Converters {

    @TypeConverter
    fun listToJson(value: List<JobWorkHistory>?): String {

        return Gson().toJson(value)
    }

    @TypeConverter
    fun jsonToList(value: String): List<JobWorkHistory>? {

        val objects = Gson().fromJson(value, Array<JobWorkHistory>::class.java) as Array<JobWorkHistory>
        val list = objects.toList()
        return list
    }
}
 

J'ai utilisé l'objet JobWorkHistory pour mon but, utilisez l'objet de votre choix

 @Database(entities = arrayOf(JobDetailFile::class, JobResponse::class), version = 1)
@TypeConverters(Converters::class)
abstract class MyRoomDataBase : RoomDatabase() {
     abstract fun attachmentsDao(): AttachmentsDao
}
 

10voto

Derrick Njeru Points 44

Voici comment je gère la conversion de liste

 public class GenreConverter {
@TypeConverter
public List<Integer> gettingListFromString(String genreIds) {
    List<Integer> list = new ArrayList<>();

    String[] array = genreIds.split(",");

    for (String s : array) {
       if (!s.isEmpty()) {
           list.add(Integer.parseInt(s));
       }
    }
    return list;
}

@TypeConverter
public String writingStringFromList(List<Integer> list) {
    String genreIds = "";
    for (int i : list) {
        genreIds += "," + i;
    }
    return genreIds;
}}
 

Et puis sur la base de données je fais comme indiqué ci-dessous

 @Database(entities = {MovieEntry.class}, version = 1)
@TypeConverters(GenreConverter.class)
 

6voto

40-Love Points 1333

A eu le même message d'erreur comme décrit ci-dessus. J'aimerais ajouter ceci: si vous obtenez ce message d'erreur dans un @Query, vous devez ajouter @TypeConverters au-dessus de l'annotation @Query.

Exemple:

 @TypeConverters(DateConverter.class)
@Query("update myTable set myDate=:myDate  where id = :myId")
void updateStats(int myId, Date myDate);
 

....

 public class DateConverter {

    @TypeConverter
    public static Date toDate(Long timestamp) {
        return timestamp == null ? null : new Date(timestamp);
    }

    @TypeConverter
    public static Long toTimestamp(Date date) {
        return date == null ? null : date.getTime();
    }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X