Java Android Room 数据库:如何处理实体中的 Arraylist?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/44986626/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android Room Database: How to handle Arraylist in an Entity?
提问by Tushar Gogna
I just implemented Room for offline data saving. But in an Entity class, I am getting the following error:
我刚刚实现了用于离线数据保存的 Room。但是在实体类中,我收到以下错误:
Error:(27, 30) error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
And the class is as following:
课程如下:
@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;
}
}
So basically I want to save the ArrayList in the database but I was not able to find anything relevant to it. Can you guide me regarding how to save an Array using Room?
所以基本上我想将 ArrayList 保存在数据库中,但我找不到与之相关的任何内容。你能指导我如何使用 Room 保存数组吗?
NOTE: MyListItems Pojo class contains 2 Strings (as of now)
注意:MyListItems Pojo 类包含 2 个字符串(截至目前)
Thanks in advance.
提前致谢。
采纳答案by CommonsWare
Option #1: Have MyListItems
be an @Entity
, as MainActivityData
is. MyListItems
would set up a @ForeignKey
back to MainActivityData
. In this case, though, MainActivityData
cannot have private ArrayList<MyListItems> myListItems
, as in Room, entities do not refer to other entities. A view model or similar POJO construct could have a MainActivityData
and its associated ArrayList<MyListItems>
, though.
选项#1:MyListItems
按@Entity
原样MainActivityData
是一个。MyListItems
会设置一个@ForeignKey
回MainActivityData
。但是,在这种情况下,MainActivityData
不能有private ArrayList<MyListItems> myListItems
,就像在 Room 中一样,实体不引用其他实体。但是,视图模型或类似的 POJO 构造可以具有 aMainActivityData
及其关联的ArrayList<MyListItems>
。
Option #2: Set up a pair of @TypeConverter
methods to convert ArrayList<MyListItems>
to and from some basic type (e.g., a String
, such as by using JSON as a storage format). Now, MainActivityData
can have its ArrayList<MyListItems>
directly. However, there will be no separate table for MyListItems
, and so you cannot query on MyListItems
very well.
选项#2:设置一对@TypeConverter
方法来ArrayList<MyListItems>
与某些基本类型(例如, a String
,例如通过使用 JSON 作为存储格式)进行转换。现在,MainActivityData
可以ArrayList<MyListItems>
直接拥有它。但是,将没有单独的表MyListItems
,因此您不能很好地查询MyListItems
。
回答by Amit Bhandari
Type Converterare made specifically for that. In your case, you can use code snippet given below to store data in DB.
Type Converter是专门为此制作的。在您的情况下,您可以使用下面给出的代码片段将数据存储在数据库中。
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;
}
}
And mention this class in your Room DB like this
并像这样在您的 Room DB 中提及此类
@Database (entities = {MainActivityData.class},version = 1)
@TypeConverters({Converters.class})
More info here
更多信息在这里
回答by live-love
Had the same error message as described above. I would like to add: if you get this error message in a @Query, you should add @TypeConverters above the @Query annotation.
有与上述相同的错误消息。我想补充一点:如果您在@Query 中收到此错误消息,您应该在@Query 注释上方添加@TypeConverters。
Example:
例子:
@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();
}
}
回答by Manohar Reddy
Kotlinversion for type converter:
类型转换器的Kotlin版本:
class Converters {
@TypeConverter
fun listToJson(value: List<JobWorkHistory>?) = Gson().toJson(value)
@TypeConverter
fun jsonToList(value: String) = Gson().fromJson(value, Array<JobWorkHistory>::class.java).toList()
}
I Used JobWorkHistory
object for my purpose, use the object of your own
我JobWorkHistory
为我的目的使用了对象,使用你自己的对象
@Database(entities = arrayOf(JobDetailFile::class, JobResponse::class), version = 1)
@TypeConverters(Converters::class)
abstract class MyRoomDataBase : RoomDatabase() {
abstract fun attachmentsDao(): AttachmentsDao
}
回答by Derrick Njeru
This is how i handle List conversion
这就是我处理列表转换的方式
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;
}}
And then on the database i do as shown below
然后在数据库上我做如下所示
@Database(entities = {MovieEntry.class}, version = 1)
@TypeConverters(GenreConverter.class)
And below is a kotlin implementation of the same;
下面是相同的 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
}}
回答by Fidan Bacaj
Use official solution from room, @Embedded annotation :
使用房间的官方解决方案,@Embedded 注释:
@Embedded(prefix = "mylist_array") private ArrayList<MyListItems> myListItems
回答by abitcode
Adding @TypeConverters
with the converter class as params
添加@TypeConverters
转换器类作为参数
to Database & to the Dao class, made my queries work
到数据库和 Dao 类,使我的查询工作
回答by Daniel Wilson
This answer uses Kotin to split by comma and construct the comma delineated string. The comma needs to go at the end of all but the last element, so this will handle single element lists as well.
此答案使用 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
}
}
回答by Dokuzov
Json conversions don't scale well in terms of memory allocation.I'd rather go for something similar to responses above with some nullability.
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(",")
}
}
For simple data types the above can be used, otherwise for complex datatypes Room provides Embedded
对于简单的数据类型可以使用上面的,否则对于复杂的数据类型 Room 提供Embedded
回答by Nitin Misra
Better version of List<String>
converter
更好的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 = ",")
}
}