Доступ и хранение нескольких классов POJO в комнате - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть несколько классов POJO в качестве типов для основного класса POJO, который я использую для анализа данных json с помощью Retrofit.Поэтому я предоставил преобразователи типов для первого уровня Pojo, но у меня возникают проблемы с чтением сохраненных данных, потому что они не в правильном формате.

Вот мой класс POJO

@Entity(tableName = "entry")
public class Entry implements Parcelable {

    @NonNull
    @PrimaryKey
    @SerializedName("id")
    private FeedID feedId;
    @SerializedName("title")
    private Title EntryTitle;
    @SerializedName("im:image")
    private List<Image> image;
    @SerializedName("summary")
    private Summary summary;

    public Entry(){}

    public FeedID getFeedId() {
        return feedId;
    }

    public void setFeedId(FeedID feedId) {
        this.feedId = feedId;
    }

    public Title getEntryTitle() {
        return EntryTitle;
    }

    public void setEntryTitle(Title entryTitle) {
        this.EntryTitle = entryTitle;
    }

    public List<Image> getImage() {
        return image;
    }

    public void setImage(List<Image> image) {
        this.image = image;
    }

    public Summary getSummary() {
        return summary;
    }

    public void setSummary(Summary summary) {
        this.summary = summary;
    }

    @SuppressWarnings("unused")
    public static final Parcelable.Creator<Entry> CREATOR = new Parcelable.Creator<Entry>() {
        @Override
        public Entry createFromParcel(Parcel in) {
            return new Entry(in);
        }

        @Override
        public Entry[] newArray(int size) {
            return new Entry[size];
        }
    };

    protected Entry(Parcel in) {
        feedId = (FeedID) in.readValue(FeedID.class.getClassLoader());
        EntryTitle = (Title) in.readValue(Title.class.getClassLoader());
        if (in.readByte() == 0x01) {
            image = new ArrayList<Image>();
            in.readList(image, Image.class.getClassLoader());
        } else {
            image = null;
        }
        summary = (Summary) in.readValue(Summary.class.getClassLoader());
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeValue(feedId);
        dest.writeValue(EntryTitle);
        if (image == null) {
            dest.writeByte((byte) (0x00));
        } else {
            dest.writeByte((byte) (0x01));
            dest.writeList(image);
        }
        dest.writeValue(summary);
    }

    public class Title implements Parcelable {
        private String label;

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        @SuppressWarnings("unused")
        public final Parcelable.Creator<Title> CREATOR = new Parcelable.Creator<Title>() {
            @Override
            public Title createFromParcel(Parcel in) {
                return new Title(in);
            }

            @Override
            public Title[] newArray(int size) {
                return new Title[size];
            }
        };

        protected Title(Parcel in) {
            label = in.readString();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(label);
        }
    }

    public class Image implements Parcelable {
        private String label;

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        @SuppressWarnings("unused")
        public final Parcelable.Creator<Image> CREATOR = new Parcelable.Creator<Image>() {
            @Override
            public Image createFromParcel(Parcel in) {
                return new Image(in);
            }

            @Override
            public Image[] newArray(int size) {
                return new Image[size];
            }
        };

        protected Image(Parcel in) {
            label = in.readString();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(label);
        }
    }

    public class Summary implements Parcelable {
        private String label;

        public String getLabel() {
            return label;
        }

        public void setLabel(String label) {
            this.label = label;
        }

        @SuppressWarnings("unused")
        public final Parcelable.Creator<Summary> CREATOR = new Parcelable.Creator<Summary>() {
            @Override
            public Summary createFromParcel(Parcel in) {
                return new Summary(in);
            }

            @Override
            public Summary[] newArray(int size) {
                return new Summary[size];
            }
        };

        protected Summary(Parcel in) {
            label = in.readString();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(label);
        }
    }

    public class FeedID implements Parcelable {

        private Attributes attributes;

        public Attributes getAttributes() {
            return attributes;
        }

        public void setAttributes(Attributes attributes) {
            this.attributes = attributes;
        }


        @SuppressWarnings("unused")
        public final Parcelable.Creator<FeedID> CREATOR = new Parcelable.Creator<FeedID>() {
            @Override
            public FeedID createFromParcel(Parcel in) {
                return new FeedID(in);
            }

            @Override
            public FeedID[] newArray(int size) {
                return new FeedID[size];
            }
        };

        protected FeedID(Parcel in) {
            attributes = (Attributes) in.readValue(Attributes.class.getClassLoader());
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeValue(attributes);
        }
    }

    public class Attributes implements Parcelable {

        @SerializedName("im:id")
        private String id;

        public String getIm() {
            return id;
        }

        public void setIm(String im) {
            this.id = im;
        }

        @SuppressWarnings("unused")
        public final Parcelable.Creator<Attributes> CREATOR = new Parcelable.Creator<Attributes>() {
            @Override
            public Attributes createFromParcel(Parcel in) {
                return new Attributes(in);
            }

            @Override
            public Attributes[] newArray(int size) {
                return new Attributes[size];
            }
        };

        protected Attributes(Parcel in) {
            id = in.readString();
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            dest.writeString(id);
        }
    }
}

иэто мой класс TypeConverter

    public class RoomTypeConverters {

    @TypeConverter
    public static String toString(Entry.Title value) {
        Gson gson = new Gson();
        String json = gson.toJson(value);
        return json;
    }

    @TypeConverter
    public static Entry.Title toTitle(String value) {
        Type listType = new TypeToken<Entry.Title>() {
        }.getType();
        return new Gson().fromJson(value, listType);
    }

    @TypeConverter
    public static String toString(Entry.FeedID value) {
        Gson gson = new Gson();
        String json = gson.toJson(value);
        return json;
    }

    @TypeConverter
    public static Entry.FeedID toFeedID(String value) {
        Type listType = new TypeToken<Entry.FeedID>() {
        }.getType();
        return new Gson().fromJson(value, listType);
    }

    @TypeConverter
    public static String toString(Entry.Summary value) {
        Gson gson = new Gson();
        String json = gson.toJson(value);
        return json;
    }

    @TypeConverter
    public static Entry.Summary toSummary(String value) {
        Type listType = new TypeToken<Entry.Summary>() {
        }.getType();
        return new Gson().fromJson(value, listType);
    }

    @TypeConverter
    public static String toString(List<Entry.Image> value) {
        Gson gson = new Gson();
        String json = gson.toJson(value);
        return json;
    }

    @TypeConverter
    public static List<Entry.Image> toImage(String value) {
        Type listType = new TypeToken<Entry.Summary>() {
        }.getType();
        return new Gson().fromJson(value, listType);
    }
}

Нужно ли создавать несколько POJO, как это только для одного поля?У нас есть другая альтернатива?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

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

@ Embedded Может использоваться в качестве аннотации для поля сущности или Pojo, чтобы сигнализировать о том, что на вложенные поля (т.е. поля класса аннотированного поля) можно ссылаться непосредственно в запросах SQL.

Например, если у вас есть 2 класса:

    public class Coordinates {
       double latitude;
       double longitude;
   }
   public class Address {
       String street;
       @Embedded
       Coordinates coordinates;
   }

Комната будет учитывать широту и долготу, как если бы они были полями класса Address при отображении строки SQLite в Address.

Источник: Документация

0 голосов
/ 24 сентября 2018

Да, чтобы сохранить POJO, вам нужно определить класс для него (внутренний или обычный класс).

Но что я понимаю из вашей схемы данных, так это то, что у вас естьвозможно сложная сторона сервера хранилища данных, и вы хотите использовать подмножество этих данных в вашем приложении.Ваш POJO может быть упрощен, так что вы можете, например, создать класс с именем EntryRecord и определить для него простой установщик и получатель следующим образом:

@Entity(tableName = "entry")
public class EntryRecord {

    @NonNull
    @PrimaryKey
    @SerializedName("id")
    private String feedId;
    @SerializedName("title")
    private StringEntryTitle;
    @SerializedName("im:image")
    private String[] image;
    @SerializedName("summary")
    private String summary;

    public EntryRecord(Entry entry){
        //Resolve primitive values from Entry class attributes..
    }

    public Entry getEntry(){
        Entry entry = new Entry();
        //Resolve entry values from primitive ones...
        return entry ;
    }
}

, теперь все, что вам нужно сделать, это использовать этот классчтобы сохранить и восстановить ваши данные, вы можете сделать ваш DAO abstract для преобразования вашего POJO перед сохранением и наоборот.

PS: если вы не используете его длясложная схема с таким количеством классов с одной переменной, я действительно советую вам определить пользовательские GSON serializer / deserializer для преобразования сложного POJO в упрощенный с самого начала;удаление такой сложной схемы полностью из вашей кодовой базы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...