Java-Android Room数据库:如何在实体中处理Arraylist?

我刚刚实现了Room来保存离线数据。 但是在Entity类中,出现以下错误:

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

该类如下:

@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;
}
}

因此,基本上我想将ArrayList保存在数据库中,但找不到任何相关的东西。 您可以指导我如何使用Room保存阵列吗?

注意:MyListItems Pojo类包含2个字符串(到目前为止)

提前致谢。

Tushar Gogna asked 2020-02-23T00:33:25Z
10个解决方案
68 votes

类型转换器是专门为此而设计的。 对于您的情况,可以使用下面给出的代码片段将数据存储在DB中。

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;
}
}

并在您的Room DB中提及此类

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

更多信息在这里

Amit Bhandari answered 2020-02-23T00:34:08Z
57 votes

选项#1:将@TypeConverter设为ArrayList<MyListItems>,就像String一样。 MainActivityData会将ArrayList<MyListItems>设置回MyListItems。在这种情况下,尽管MyListItems不能具有private ArrayList<MyListItems> myListItems,因为在Room中,实体不会引用其他实体。 但是,视图模型或类似的POJO构造可以具有MainActivityData及其关联的ArrayList<MyListItems>

选项#2:设置一对@TypeConverter方法,以将ArrayList<MyListItems>与某种基本类型(例如String,例如通过使用JSON作为存储格式)来回转换。 现在,MainActivityData可以直接拥有ArrayList<MyListItems>。 但是,将没有单独的表MyListItems,因此您无法很好地查询MyListItems

CommonsWare answered 2020-02-23T00:33:39Z
25 votes

类型转换器的Kotlin版本:

 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
    }
}

我已将JobWorkHistory对象用于我的目的,请使用您自己的对象

@Database(entities = arrayOf(JobDetailFile::class, JobResponse::class), version = 1)
@TypeConverters(Converters::class)
abstract class MyRoomDataBase : RoomDatabase() {
     abstract fun attachmentsDao(): AttachmentsDao
}
Manohar Reddy answered 2020-02-23T00:34:33Z
7 votes

这就是我处理列表转换的方式

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;
}}

然后在数据库上我如下所示

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

下面是相同的Kotlin实现;

class GenreConverter {
@TypeConverter
fun gettingListFromString(genreIds: String): List<Int> {
    val list = mutableListOf<Int>()

    val array = genreIds.split(",".toRegex()).dropLastWhile {
        it.isEmpty()
    }.toTypedArray()

    for (s in array) {
        if (s.isNotEmpty()) {
            list.add(s.toInt())
        }
    }
    return list
}

@TypeConverter
fun writingStringFromList(list: List<Int>): String {
    var genreIds=""
    for (i in list) genreIds += ",$i"
    return genreIds
}}
Derrick Njeru answered 2020-02-23T00:35:01Z
6 votes

具有与上述相同的错误消息。我想添加:如果在@Query中收到此错误消息,则应在@Query注释上方添加@TypeConverters。

例:

@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();
    }
}
live-love answered 2020-02-23T00:35:30Z
3 votes

更好的版本List<String>转换器

class StringListConverter {
    @TypeConverter
    fun fromString(stringListString: String): List<String> {
        return stringListString.split(",").map { it }
    }

    @TypeConverter
    fun toString(stringList: List<String>): String {
        return stringList.joinToString(separator = ",")
    }
}
Nitin Misra answered 2020-02-23T00:35:50Z
1 votes

该答案使用Kotin用逗号分隔并构造逗号分隔的字符串。 逗号需要放在除最后一个元素之外的所有元素的末尾,因此它也将处理单个元素列表。

object StringListConverter {
        @TypeConverter
        @JvmStatic
        fun toList(strings: String): List<String> {
            val list = mutableListOf<String>()
            val array = strings.split(",")
            for (s in array) {
                list.add(s)
            }
            return list
        }

        @TypeConverter
        @JvmStatic
        fun toString(strings: List<String>): String {
            var result = ""
            strings.forEachIndexed { index, element ->
                result += element
                if(index != (strings.size-1)){
                    result += ","
                }
            }
            return result
        }
    }
Daniel Wilson answered 2020-02-23T00:36:10Z
0 votes

@TypeConverters添加为转换器类作为参数

数据库和Dao类,使我的查询工作

abitcode answered 2020-02-23T00:36:35Z
0 votes

Json转换在内存分配方面不能很好地扩展,我宁愿进行类似于上述响应且具有可空性的操作。

class Converters {
    @TypeConverter
    fun stringAsStringList(strings: String?): List<String> {
        val list = mutableListOf<String>()
        strings
            ?.split(",")
            ?.forEach {
                list.add(it)
            }

        return list
    }

    @TypeConverter
    fun stringListAsString(strings: List<String>?): String {
        var result = ""
        strings?.forEach { element ->
            result += "$element,"
        }
        return result.removeSuffix(",")
    }
}

对于简单数据类型,可以使用上面的方法,否则对于复杂数据类型,Room提供嵌入式

Dokuzov answered 2020-02-23T00:36:59Z
-1 votes

使用来自房间的官方解决方案@Embedded注解:

@Embedded(prefix = "mylist_array") private ArrayList<MyListItems> myListItems
Fidan Bacaj answered 2020-02-23T00:37:19Z
translate from https://stackoverflow.com:/questions/44986626/android-room-database-how-to-handle-arraylist-in-an-entity