web-dev-qa-db-ja.com

Androidルームにオブジェクトを保存する方法は?

基本的に、理解できないことが2つあります。オブジェクトを持つオブジェクトとオブジェクトのリストを持つオブジェクト

サーバーからオブジェクトのリストを受け取ったとします。それぞれは次のようになります。

@Entity
public class BigObject {
    @PrimaryKey
    private int id;
    private User user;
    private List<SmallObject> smallObjects;
}

これらの2つのオブジェクトをフィールドとして:

@Entity
public class User {
    @PrimaryKey
    private int id;
    private String name;
    @TypeConverters(GenderConverter.class)
    public MyEnums.Gender gender;
}

@Entity
public class SmallObject {
    @PrimaryKey (autoGenerate = true)
    private int id;
    private String smallValue;
}

これらはこれよりも複雑なので、Roomが提案するように@TypeConvertersを使用することはできません。

error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.

このデータ構造をRoomに保存するにはどうすればよいですか?

14
ildar ishalin

これに答える最良の方法は、構造を保存する簡単な概要です...

リスト

Roomは、POJO内にネストされたリストの保存をサポートしていません。リストを保存するための推奨される方法は、外部キーアプローチを使用することです。オブジェクトのリストを、関連する親オブジェクト(この場合は "big_object_id")への外部キーを使用して別のテーブル(この場合はsmallObjectsテーブル)に格納します。次のようになります...

@Entity
public class BigObject {
    @PrimaryKey
    private int id;
    private User user;
    @Ignore
    private List<SmallObject> smallObjects;
}

@Entity(foreignKeys = {
            @ForeignKey(
                entity = BigObject.class,
                parentColumns = "id",
                childColumns = "big_object_fk"
            )})
public class SmallObject {
    @PrimaryKey (autoGenerate = true)
    private int id;
    private String smallValue;
    @ColumnInfo(name = "big_object_fk")
    private int bigObjectIdFk
}

@Ignore注釈List<SmallObject>(リストがサポートされていないため)ルームの永続化中にフィールドを無視するため。これで、DBから関連する小さなオブジェクトのリストを要求したときに、POJOに保存できるようになりました。

私の知る限り、これは2つのクエリを実行していることを意味します。

BigObject b = db.BigObjectDao.findById(bOId);
List<SmallObject> s = db.smallObjectDao.findAllSOforBO(bOId);
b.setsmallObjects(s);

@ Relation の形式でこれの省略形があるようです

タイプコンバーター

これらは、情報を失うことなくフラットテンドであり、単一の列に格納できる複雑なデータ構造がある場合です。この良い例は、Dateオブジェクトです。 Dateオブジェクトは複雑で多くの値を保持しているため、データベースに保存するのは簡単ではありません。型コンバーターを使用して、日付オブジェクトのミリ表現を抽出し、保存します。その後、ミリを日付オブジェクトに変換して、データをそのまま保持します。

埋め込み

これは、親POJO内のすべてのネストされたPOJOのフィールドを取得し、それらをフラット化して1つのテーブルに格納する場合に使用されます。例 :

- name
- age
- location
    - x 
    - y
- DOB

..埋め込まれると、この構造は次のようにデータベースに格納されます。

- name 
- age 
- location_x
- location_y
- DOB

ある意味では、Embeddedは、String、int、floatなどのプライマリタイプフィールドを含むすべてのネストされたオブジェクトのタイプコンバーターを作成する時間を節約するために存在します...

30
Jack Dalton

オブジェクトの変換/ List<Object>を文字列に変換してから保存します。

オブジェクトをルームライブラリに文字列として保存できます。そのために、オブジェクトをシリアル化して、部屋データベースに文字列として保存できます。

部屋に保管

オブジェクト->シリアル化->文字列->ストア

部屋からの読み取り

文字列->デシリアライズ->オブジェクト->読み取り

シリアライズ/デシリアライズする方法は?

利用可能な多くのオプションがあります。手動で行うことも、このためのライブラリを使用することもできます。 Googleの GSONライブラリ を使用できます。使い方はかなり簡単です。

コード:オブジェクト->文字列

public String stringFromObject(List<YourClass> list){

    Gson gson = new Gson();
    String jsonString = gson.toJson(list);
    return jsonString;

}

コード:文字列->オブジェクト

public List<YourClass> getObjectFromString(String jsonString){

    Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
    List<YourClass> list = new Gson().fromJson(jsonString, listType);
    return list;

}
0
Rohit Singh