有没有一种方法可以在Room的列中存储可变数据类型

时间:2020-02-05 18:43:14

标签: java android sqlite kotlin android-room

我刚刚开始一项新工作,分配给我的第一个主要任务是将我们的应用程序从使用自定义SQLiteHelper实现升级到使用Room。

当前,我们有一个表,该表实际上只是键/值对的表,其中值是变量(即有时变量是String,long,int或boolean)[总是原始类型],但存储为String 。这是通过使POJO对象具有以下结构来实现的:

public class KeyValue {
    private static final String TAG = KeyValues.class.getSimpleName();
    Map<String, String> _map;

    public Iterable<? extends Map.Entry<String, String>> entrySet() {
        return _map.entrySet();
    }

    public void put(String key, Object value){
        _map.put(key, val == null ? null : val.toString());
    }

    public String getString(String key) {
        return _map.get(key);
    }

    public String getString(String key, String defaultValue) {
        String value = getString(key);
        return value == null ? defaultValue : value;
    }

    public int getInt(String key) {
        String value = _map.get(key);
        if (value == null) return 0;
        try {
            return Integer.parseInt(value);
        } catch (NumberFormatException nfe) {
           Reporter.w(TAG, "Could not parse int %s : %s", key, value)
           return 0;
        }
    }

    public long getLong(String key) {
        return getLong(key, 0L);
    }

    public long getLong(String key, long defaultValue) {
        String value = _map.get(key);
        if (value == null) return defaultValue;
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException nfe) {
            Reporter.w(TAG, "Could not parse long %s : %s", key, value)
            return 0L;
        }
    }

    public boolean getBoolean(String key, boolean defaultValue) {
        String value = _map.get(key);
        if (value == null) return defaultValue;
        if ("true".equals(value)) return true;
        if ("false".equals(value)) return false;
        Reporter.w(TAG, "Could not parse boolean %s : %s", key, value)
        return defaultValue;
    }
} 

这基本上与共享首选项相同,键是应用程序中的所有常量,而不是从我们的服务器中提取的数据,并且值都是原语。

我现在没有时间将代码的这一部分转换为共享的状态,因为我对Room的实现很忙。所以我想知道是否有一种无需使用字符串转换即可完成此操作的方法。

我当前正在使用的新对象看起来像这样(我实际上只是在尝试不进行字符串转换):

@Entity(tableName = "key_values", indices = [Index(value = ["_key"], unique = true)])
class KeyValue {

    private val TAG = KeyValue::class.java.simpleName

    @PrimaryKey
    @ColumnInfo(name = "_key")
    var key = ""

    @ColumnInfo(name = "value")
    var value = ""

    fun getValueAsInt(): Int {
        try {
            return value.toInt()
        } catch (exception: NumberFormatException) {
            Reporter.w(TAG, "Could not parse int %s : %s", key, value)
            throw exception
        }

    }

    fun getValueAsLong(): Long {
        try {
            return value.toLong()
        } catch (exception: NumberFormatException) {
            Reporter.w(TAG, "Could not parse long %s : %s", key, value)
            throw exception
        }
    }

    fun getValueAsBool(): Boolean {
        if (value.equals("true", true) || value.equals("false", true)) {
            return value.toBoolean()
        } else {
            throw ClassCastException("Not a boolean")
        }
    }
}

我真的很想能够做类似的事情:

    int value = keyValue.getValue();

    long value = keyValue.getValue();

代替

    int value = keyValue.getValueAsInt();

    long value = keyValue.getValueAsLong();

此外,我正在Kotlin中实现Room,但由于我们尚未开始将旧代码转换为Kotlin,因此许多此类方法将在Java类中使用。

1 个答案:

答案 0 :(得分:0)

我认为没有办法得到想要的东西,所以我最终使用了“ getValueAs”函数。