Могу ли я использовать один единственный 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)
}