在 Realm 中存储关系 (Java)

Storing relationships in Realm (Java)

我开始使用 Realm 在我的 Android 应用程序中存储对象。这是我要存储的示例:

public class Item implements RealmModel {
    String id;
    ...
}

我有多个显示项目的列表。列表数量可以不断扩大(用户可以创建尽可能多的列表。

假设用户创建了一个名为 "Best" 的列表。当我查看 "Best" 列表时,我调用 getItems("Best") 从 API 获取 List<Items>。我现在必须弄清楚如何存储这个列表。例如,在 SQLite 世界中,我会创建一个新的 table "custom_list_best",它只是列表中所有 Item.id 的一个列表。我还会有一个包含所有不同项目的 "items" table。要获得最佳列表中的项目,我只需对最佳和项目 tables.

进行连接查询

在 Realm 世界中,我正在尝试了解 Realm 的工作原理以及构建模型的最佳方式。

我最初认为我可以创建一个名为 CustomList:

的对象
public class CustomList implements RealmModel {
    String listId;
    RealmList<Item> items;
}

然后我会存储一个 RealmList<CustomList>。但唯一的问题是我还希望能够查询所有项目。所以我还需要在 Realm 中存储一个 RealmList<Item> 。在这种情况下,Realm 是如何工作的?如果我存储一个单独的 RealmList<Item> 然后存储每个 RealmList<CustomList> 它不会重复数据吗?

相反,我是否必须通过以下方式手动处理此问题:

public class CustomList implements RealmModel {
    String listId;
    List<String> itemIds;
}

然后从上述对象中查询 Item.class 个在 itemIds 中有 itemId 的对象?

In SQLite world I would have create a new table "custom_list_best",

不,您将有一个名为 custom_lists 的 table,它带有一个自动递增 ID 和一个标识符,以及一个名为 join_custom_lists_items 的连接 table,它将包含custom_lists 的 ID 和属于该给定自定义列表的任何 item 的 ID。

In the Realm world I'm trying to figure out how Realm works and what's the best way to build my models.

如果项目的 ID 是具体的,并且您需要能够在多个列表中存储相同的 Item,那么为了双向访问列表,您将在这两种情况下都需要 RealmList<? extends RealmModel>

@RealmClass
public class Item implements RealmModel {
    @PrimaryKey
    private String id;

    private RealmList<CustomList> customLists;

    // getter setter
}

@RealmClass
public class CustomList implements RealmModel {
    @PrimaryKey
    private String title; // assuming you cannot name two lists the same? otherwise do `@Index`

    private RealmList<Item> items;

    // getter setter
}

你可以这样做

realm.executeTransaction(new Realm.Transaction() {
  public void execute(Realm realm) {
    Item item = realm.where(Item.class).equalTo(ItemFields.ID, itemId).findFirst(); // assuming exists
    CustomList customList = realm.where(CustomList.class).equalTo(CustomListFields.TITLE, "Best").findFirst();
    if(customList == null) {
         customList = realm.createObject(CustomList.class, "Best");
    }
    customList.getItems().add(item);
    item.getCustomLists().add(customList);
  }
}

然后就可以查询了

RealmResults<Item> bestItems = realm.where(Item.class)
                                    .equalTo(ItemFields.CustomLists.TITLE, "Best")
                                            //same as "customLists.title"
                                    .findAll();

我使用的所有 Fields 东西都来自 https://github.com/cmelchior/realmfieldnameshelper