Могу ли я использовать один единственный TypeConverter для разных типов объектов?

До сих пор для хранения в Room Database я использовал конвертер типов для каждого класса. Как это:

@SerializedName("sidebar")
@Expose
@TypeConverters(SidebarConverter.class)
private Sidebar sidebar;
@SerializedName("splash")
@Expose
@TypeConverters(SplashConverter.class)
private Splash splash;
@SerializedName("overview")
@Expose
@TypeConverters(OverviewConverter.class)
private Overview overview;
@SerializedName("home")
@Expose
@TypeConverters(HomeConverter.class)
private Home home;
@SerializedName("portfolio")
@Expose
@TypeConverters(PortfolioConverter.class)
private Portfolio portfolio;
@SerializedName("team")
@Expose
@TypeConverters(TeamConverter.class)
private Team team;

Я хочу знать, есть ли более удобный способ использовать один TypeConverter в одиночку в базе данных.

2 ответа

Вы можете определить все ваши конвертеры в одном классе следующим образом:

public class DateTypeConverter {

    @TypeConverter
    public static Date toDate(Long value) {
        return value == null ? null : new Date(value);
    }

    @TypeConverter
    public static Long toLong(Date value) {
        return value == null ? null : value.getTime();
    }
}

А затем установите этот конвертер в вашей базе данных комнат с помощью @TypeConverter аннотация, как это, которые работают глобально на любом @Entity класс. Вам не нужно определять @TypeConverter Индивидуально в классе Entity

@Database(entities = {Product.class}, version = 1)
@TypeConverters({DateTypeConverter.class})
public abstract class MyDatabase extends RoomDatabase {
    public abstract ProductDao productDao();
}

Обратите внимание, что мы добавили новую аннотацию с именем @TypeConverters в нашем определении базы данных для ссылки на различные конвертеры, которые мы можем иметь (вы можете разделить его запятыми и добавить другие).

Проблема здесь в том, что генерирование кода Room пытается найти определенный тип, и если вы попытаетесь сделать универсальный конвертер, он не сможет сгенерировать соответствующие методы. Тем не менее, если в вашем случае целесообразно преобразовать данные в json для хранения, вы можете уменьшить шаблон следующим образом:

@TypeConverter
fun toSomething(value: String): Something = fromJson(value)

@TypeConverter
fun fromSomething(value: Something): String = toJson(value)

fromJson и toJson являются общими, например, они могут выглядеть следующим образом. В любое время, когда вам нужно добавить типы, просто возьмите два вышеупомянутых метода и замените "Something" на ваш тип. Если вам нужно преобразовать много классов, вы даже можете легко преобразовать TypeConverter в код такого типа, чтобы удовлетворить потребности Room в коде.

inline fun <reified T> fromJson(value: String): T {
    val jsonAdapter = moshi.adapter(T::class.java)
    return jsonAdapter.fromJson(value)
}

inline fun <reified T> toJson(value: T): String {
    val jsonAdapter = moshi.adapter(T::class.java)
    return jsonAdapter.toJson(value)
}
Другие вопросы по тегам