Есть ли способ сохранить переменный тип данных в столбце в комнате - PullRequest
0 голосов
/ 05 февраля 2020

Я только начал новую работу, и первая важная задача, которую мне назначили, состояла в том, чтобы обновить наше приложение с использования пользовательской реализации SQLiteHelper до использования Room.

В настоящее время у нас есть таблица, которая буквально является просто таблицей Пары ключ / значение, где значение является переменной (ie иногда переменная является 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. Поэтому мне было интересно, есть ли способ сделать это sh без использования преобразования строк.

Мой текущий новый объект, который я использую, выглядит следующим образом (я просто пытаюсь не выполнять преобразование строк):

@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, но многие из этих методов будут использоваться в Java классах, так как мы еще не начали преобразовывать старый код в Kotlin

1 Ответ

0 голосов
/ 13 апреля 2020

Я не думаю, что был способ получить то, к чему я стремился, поэтому я в итоге использовал функции "getValueAs".

...