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;

public String getUserId() {

return userId;

}

public void setUserId(String userId) {

this.userId = userId;

}

public ArrayList getMyListItems() {

return myListItems;

}

public void setCheckListItems(ArrayList myListItems) {

this.myListItems = myListItems;

}

}

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

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

提前致谢。

10个解决方案

68 votes

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

public class Converters {

@TypeConverter

public static ArrayList fromString(String value) {

Type listType = new TypeToken>() {}.getType();

return new Gson().fromJson(value, listType);

}

@TypeConverter

public static String fromArrayList(ArrayList 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,就像String一样。 MainActivityData会将ArrayList设置回MyListItems。在这种情况下,尽管MyListItems不能具有private ArrayList myListItems,因为在Room中,实体不会引用其他实体。 但是,视图模型或类似的POJO构造可以具有MainActivityData及其关联的ArrayList。

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

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

25 votes

类型转换器的Kotlin版本:

class Converters {

@TypeConverter

fun listToJson(value: List?): String {

return Gson().toJson(value)

}

@TypeConverter

fun jsonToList(value: String): List? {

val objects = Gson().fromJson(value, Array::class.java) as Array

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 gettingListFromString(String genreIds) {

List 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 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 {

val list = mutableListOf()

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): 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转换器

class StringListConverter {

@TypeConverter

fun fromString(stringListString: String): List {

return stringListString.split(",").map { it }

}

@TypeConverter

fun toString(stringList: List): 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 {

val list = mutableListOf()

val array = strings.split(",")

for (s in array) {

list.add(s)

}

return list

}

@TypeConverter

@JvmStatic

fun toString(strings: List): 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 {

val list = mutableListOf()

strings

?.split(",")

?.forEach {

list.add(it)

}

return list

}

@TypeConverter

fun stringListAsString(strings: List?): 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

Fidan Bacaj answered 2020-02-23T00:37:19Z

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐