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

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

@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
0
4 721
2

Ответы 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 в определение нашей базы данных, чтобы указать различные преобразователи, которые у нас могут быть (вы можете разделить ее запятыми и добавить другие).

Но для каждого класса будут разные методы. Что вы говорите о создании класса и копировании всех остальных кодов @TypeConverters для разных классов в этот конкретный класс?

Farwa 21.03.2018 05:21

Либо вы можете поместить все это в один класс, либо, если у вас уже есть несколько классов для нескольких конвертеров, вы можете ссылаться на разные конвертеры через запятую в @TypeConverters({SidebarConverter.class,SplashConverter.clas‌​s,PortfolioConverter‌​.class}).

Burhanuddin Rashid 21.03.2018 05:25

Так что по-прежнему много повторяющегося кода. Значит, нет универсального способа?

Farwa 21.03.2018 05:29

Нет, на данный момент нет универсального способа, но этот подход имеет меньше шаблонного кода, чем ваша текущая реализация. Он определяет ваши преобразователи глобально, а не для каждого объекта в классе Entity

Burhanuddin Rashid 21.03.2018 05:31

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

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

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

fromJson и toJson являются общими, например они могут выглядеть так. Каждый раз, когда вам нужно добавить типы, просто воспользуйтесь двумя описанными выше методами и замените «Something» своим типом. Если у вас есть много классов для преобразования, вы можете довольно легко даже использовать TypeConverters для генерации кода, чтобы удовлетворить потребности генерации кода 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)
}

К сожалению, это решение не работает с комнатой. Ошибка: e: /Users/adamhurwitz/Code/CryptoTweets/app/build/tmp/kapt3/stu‌​bs/debug/app/cryptot‌​weets/feed/models/en‌​tities/Entities.java‌​:8: error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

Adam Hurwitz 08.03.2020 19:42

Другие вопросы по теме