【问题标题】:How does the @LinkingObjects annotation in Realm workRealm 中的@LinkingObjects 注解是如何工作的
【发布时间】:2020-01-10 08:28:34
【问题描述】:

我有一个使用带有 json1 扩展名的 SQLite 作为其数据库后端的 Android 应用程序。虽然这可行,但操作 JSON 所需的 SQL 却很难理解,甚至更难维护。因此,我目前正在尝试使用 Realm 作为替代方案。虽然 Realm 在很大程度上是直观的,但 LinkingObjects 是一个我不完全理解的功能。考虑以下我目前使用的类

public class GridNode extends RealmObject
{
 @PrimaryKey
 private int id = 0;   
 @Index
 private int lx = 0;
 @Index
 private int ly = 0;

 @LinkingObjects("gridnode")
 private final RealmResults<PassPoint> passpoints = null;

 //getters, setters & constructors
}


public class PassPoint extends RealmObject
{
 private GridNode gridnode;//each passpoint refers to one distinct GridNode object
 private int hits;
 private int lastVisited;

 //getters, setters & constructors
} 

在我的数据的当前 SQLite 版本中,我通过引用其 AUTO_INCREMENTing id 字段来识别每个 PassPoint 使用的 GridNode。有了 Realm,事情就变得简单多了,因为我可以简单地将 GridNode 本身用作 PassPoint 的一个属性。

这就是事情变得不太清楚的地方。假设我通过运行 RealmQuery 从Realm 检索现有的GridNode,例如

myrealm.where(GridNode.class).equalTo("lx",23).equalTo("ly",32).findFirst();

在字里行间我得出结论,运行此查询不仅会获取我所追求的 GridNode,而且会使用我的

运行隐式查询
@LinkingObjects("gridnode")
private final RealmResults<PassPoint> passpoints = null;

用于检索引用相关 GridNode 的所有 PassPoint 对象列表的注释。

非常方便,但我发现自己想知道这是否不付出代价 - 运行该查询所需的时间。假设我还有一些其他类也引用了 GridNodes,在这种情况下,我将有更多的 @LinkingObjets 注释,这会导致进一步的隐式查询?

与此相反,如果我只是记录一个 GridNode id,我可以在需要时自己处理识别相关的 GridNode?实际上,以便利换取速度和响应能力?

或者也许我只是在字里行间读错了,这根本不是@LinkingObjects 的工作原理?

另一件不太清楚的事情——你会注意到gridnodePassPoint 类的私有成员。那么我如何能够在我的GridNode 类中创建@LinkingObjects("gridnode") 注释,而编译器不会抱怨我试图访问从PassPoint 类外部不可见的成员?

【问题讨论】:

    标签: java android sqlite realm linkingobjects


    【解决方案1】:

    在字里行间我得出结论,运行此查询不仅会获取我所追求的 GridNode,还会运行隐式查询

    没有。不完全是。

    正如 Realm 文档所述 here

    Realm 中的所有获取(包括查询)都是惰性的,并且永远不会复制数据。

    这意味着定义查询的简单案例就是这样做的——它定义了它。但在用户明确请求之前,它不会评估/执行查询。因此,具有查询字段(例如LinkingObjects 字段)的对象提供了一种简单的方法,用户可以通过该方法执行查询,但不会因为对象本身已加载而自动执行。它仅在进行findFirstfindAll(或类似)调用时运行。

    因此,如果您从未真正访问过GridNode.passpoints 字段,则它永远不会被执行。

    你可以通过一个简单的实验来证明这一点:-

    1. 从没有链接PassPoint的领域中检索GridNode
    2. 访问链接对象字段并检查它是否为空。
    3. 将新的Passpoint 添加到领域,并引用相同的GridNode
    4. 重新测试您在第 1 步中检索到的同一对象的链接对象字段,您应该会看到查询结果现在包含新的 Passpoint

    关于您的第二个问题,简单的答案是您的模型字段的保护级别仅适用于您数据的 Java 模型;它不适用于底层 Realm 模型。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 2015-09-29
      • 1970-01-01
      • 2015-10-09
      相关资源
      最近更新 更多