如何在没有字段的实体上使用Android Room?

时间:2018-08-17 21:11:40

标签: android android-room

我有一个由HashMap支持的java对象,因此没有可通过反射发现的纯字段。例如:

public class City {
    private final HashMap<String, String> internalMap = new HashMap<String, String>();

    public String getId() {
        return internalMap.get("id");
    }

    public void setId(String id) {
        internalMap.put("id", id);
    }

    public String getName() {
        return internalMap.get("name");
    }

    public void setName(String name) {
        internalMap.put("name", name);
    }
}

我想使用这样的类作为Room中的实体,而不必更改其结构,因为我有许多这样的类,这些类是使用代码生成工具自动生成的,并且出于某些特殊原因,它们需要由HashMap支持。 HashMap的每个值都应该以我的数据库表中的一列结尾(关键字String是内部实现细节)。可能吗?由于注释处理器如何发现字段,目前似乎还不是。

2 个答案:

答案 0 :(得分:0)

您可以为此使用TypeConverter。 例如,您可以使用GSON提供的序列化功能,轻松将地图转换为序列化状态,反之亦然。

class MapConverter {
    @TypeConverter
    public String fromMap(HashMap<String, String> map) {
        return new Gson().toJson(map);
    }

    @TypeConverter
    public HashMap<String, String> fromString(String serializedMap) {
        Type type = new TypeToken<HashMap<String, String>>(){}.getType();
        return gson.fromJson("serializedMap", type);
    }
}

在您的实体类中:

@Entity
@TypeConverters({MapConverter.class})
public class CityEntity {
//...
private final HashMap<String, String> internalMap;
//...
}

因此,该实体将可以使用转换器将哈希映射序列化为字符串,反之亦然。 Gson只是一种可能的解决方案,您实际上可以使用所需的任何东西。

答案 1 :(得分:0)

房间有自己的annotations集合-如果您不想映射字段,则必须通过注释POJO来向注释处理器表明这一点;例如。 @Entity,而不分配tableName,也无需忽略该字段上方的@Ignore

@Entity
public class City {

    @Ignore
    private final HashMap<String, String> internalMap = new HashMap<>();

    /* concerning the second part of the question: */
    public HashMap<String, Object> toHashMap() {
        return this.internalMap;
    }
}

这些吸气剂还有一个基本的问题,即尽管HashMap可能没有被所有(或任何一个)键填充,但它们假定所有键都会存在。 absurd代表具有两种不同类型对象的城市-一种可以完全控制要映射的字段和哪些字段可以忽略(一种可能的方法不必在此排除另一种方法)...返回HashMap的方法可能很有用,例如。以便将其插入Firebase。

我宁愿使用保留值的字段,但仍然能够返回HashMap

@Entity(tableName = "cities")
public class City {

    @ColumnInfo(name = "cityId")
    @PrimaryKey(autoGenerate = true)
    private int cityId = -1;

    @ColumnInfo(name = "cityName")
    private String cityName = null;

    ...

    /* concerning the second part of the question: */
    public HashMap<String, Object> toHashMap() {
        HashMap<String, Object> values = new HashMap<>();
        if(this.cityId   !=   -1) {values.put(  "id", this.cityId);}
        if(this.cityName != null) {values.put("name", this.cityName);}
        return values;
    }
}

这样的toHashMap()方法还提供控制,返回的HashMap应当包含哪些字段,而带有TypeConverterGSON的示例将(按原样)转换整个HashMap