Tus*_*gna 49 java android android-room
我刚刚实施了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.
Run Code Online (Sandbox Code Playgroud)
课程如下:
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
所以基本上我想将ArrayList保存在数据库中,但我无法找到与之相关的任何内容.你可以指导我如何使用房间保存阵列吗?
注意:MyListItems Pojo类包含2个字符串(截至目前)
提前致谢.
Ami*_*ari 71
Type Converter专门为此而制造.在您的情况下,您可以使用下面给出的代码段将数据存储在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;
}
}
Run Code Online (Sandbox Code Playgroud)
并在你的房间DB中提到这个类
@Database (entities = {MainActivityData.class},version = 1)
@TypeConverters({Converters.class})
Run Code Online (Sandbox Code Playgroud)
更多信息在这里
Com*_*are 58
选项1:有MyListItems是@Entity,因为MainActivityData是.MyListItems会@ForeignKey回来的MainActivityData.但是,在这种情况下,MainActivityData不能private ArrayList<MyListItems> myListItems像在Room中一样,实体不会引用其他实体.但是,视图模型或类似的POJO构造可以具有a MainActivityData和它的关联ArrayList<MyListItems>.
选项#2:设置一对@TypeConverter方法来转换ArrayList<MyListItems>为某种基本类型(例如,String使用JSON作为存储格式).现在,MainActivityData可以ArrayList<MyListItems>直接拥有它.但是,没有单独的表格MyListItems,所以你不能很好地查询MyListItems.
Man*_*ddy 29
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
}
}
Run Code Online (Sandbox Code Playgroud)
我将JobWorkHistory对象用于我的目的,使用你自己的对象
@Database(entities = arrayOf(JobDetailFile::class, JobResponse::class), version = 1)
@TypeConverters(Converters::class)
abstract class MyRoomDataBase : RoomDatabase() {
abstract fun attachmentsDao(): AttachmentsDao
}
Run Code Online (Sandbox Code Playgroud)
Nit*_*sra 21
更好的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 = ",")
}
}
Run Code Online (Sandbox Code Playgroud)
can*_*ler 21
科特林答案
你需要做三件事:
逐步使用示例:
步骤1 :
class Converters {
@TypeConverter
fun listToJsonString(value: List<YourModel>?): String = Gson().toJson(value)
@TypeConverter
fun jsonStringToList(value: String) = Gson().fromJson(value, Array<YourModel>::class.java).toList()
}
Run Code Online (Sandbox Code Playgroud)
第2步 :
@Database(entities = [YourEntity::class], version = 1)
@TypeConverters(Converters::class)
abstract class YourDatabase : RoomDatabase() {
abstract fun yourDao(): YourDao
}
Run Code Online (Sandbox Code Playgroud)
步骤3:
注意:您不需要调用Converter 的函数listToJsonString()和jsonStringToList()。他们在Room的后台使用。
@Entity(tableName = "example_database_table")
data class YourEntity(
@PrimaryKey(autoGenerate = true) val id: Long = 0,
@ColumnInfo(name = "your_model_list") var yourModelList: List<YourModel>,
)
Run Code Online (Sandbox Code Playgroud)
Pat*_*ick 13
使用 Kotlin 的序列化组件 – kotlinx.serialization 的原生 Kotlin 版本。
build.gradle:apply plugin: 'kotlinx-serialization'
dependencies {
...
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.0.1"
}
Run Code Online (Sandbox Code Playgroud)
class Converters {
@TypeConverter
fun fromList(value : List<String>) = Json.encodeToString(value)
@TypeConverter
fun toList(value: String) = Json.decodeFromString<List<String>>(value)
}
Run Code Online (Sandbox Code Playgroud)
@TypeConverters(Converters::class)
abstract class YourDatabase: RoomDatabase() {...}
Run Code Online (Sandbox Code Playgroud)
你完成了!
额外资源:
小智 9
我个人建议不要使用@TypeConverters/serializations,因为它们破坏了数据库的正常形式合规性。
对于这种特殊情况,可能值得使用@Relation批注定义关系,它允许将嵌套实体查询到单个对象中,而不会增加声明 a和手动编写所有 SQL 查询的复杂性:@ForeignKey
@Entity
public class MainActivityData {
@PrimaryKey
private String userId;
private String itemOneId;
private String itemTwoId;
}
@Entity
public class MyListItem {
@PrimaryKey
public int id;
public String ownerUserId;
public String text;
}
/* This is the class we use to define our relationship,
which will also be used to return our query results.
Note that it is not defined as an @Entity */
public class DataWithItems {
@Embedded public MainActivityData data;
@Relation(
parentColumn = "userId"
entityColumn = "ownerUserId"
)
public List<MyListItem> myListItems;
}
/* This is the DAO interface where we define the queries.
Even though it looks like a single SELECT, Room performs
two, therefore the @Transaction annotation is required */
@Dao
public interface ListItemsDao {
@Transaction
@Query("SELECT * FROM MainActivityData")
public List<DataWithItems> getAllData();
}
Run Code Online (Sandbox Code Playgroud)
除了这个 1-N 示例之外,还可以定义 1-1 和 NM 关系。
这就是我处理List转换的方式
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;
}}
Run Code Online (Sandbox Code Playgroud)
然后在数据库上我做如下所示
@Database(entities = {MovieEntry.class}, version = 1)
@TypeConverters(GenreConverter.class)
Run Code Online (Sandbox Code Playgroud)
有如上所述的相同错误消息.我想补充一点:如果在@Query中收到此错误消息,则应在@Query注释上方添加@TypeConverters.
例:
@TypeConverters(DateConverter.class)
@Query("update myTable set myDate=:myDate where id = :myId")
void updateStats(int myId, Date myDate);
Run Code Online (Sandbox Code Playgroud)
....
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();
}
}
Run Code Online (Sandbox Code Playgroud)