Как работает аннотация @LinkingObjects в Realm - PullRequest
0 голосов
/ 10 января 2020

У меня есть приложение Android, которое использует SQLite с расширением json1 в качестве базы данных. Хотя это работает, SQL, необходимый для манипулирования JSON, очень трудно понять и еще сложнее поддерживать. Следовательно, я в настоящее время экспериментирую с Царством в качестве альтернативы. Хотя 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 я идентифицирую GridNode, используемый каждым PassPoint, ссылаясь на его поле AUTO_INCREMENTing id. С Realm все становится намного проще, поскольку я могу просто использовать сам GridNode в качестве атрибута PassPoint.

Здесь все становится немного менее понятным. Предположим, я извлекаю существующий GridNode из Realm, выполняя RealmQuery, например:

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

Чтение между строками, которые я пришел к выводу, что выполнение этого запроса будет не только получать GridNode, который я ищу, но и запускать неявный запрос с использованием моей

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

аннотации для получения списка всех PassPoint объектов, которые ссылаются на рассматриваемый GridNode.

Очень удобно, но я задаюсь вопросом, не приходит ли это по цене - время, необходимое для выполнения этого запроса. И предположим, у меня есть несколько других классов, которые также ссылаются на GridNodes, и в этом случае у меня будет дополнительная аннотация @LinkingObjets, которая затем приведет к дальнейшим неявным запросам?

В отличие от этого, если бы я просто записал Идентификатор GridNode. Тогда я смогу самостоятельно определить соответствующий GridNode, как и когда это потребуется? В действительности, торговое удобство для скорости и отзывчивости?

Или, может быть, я просто неправильно прочитал между строк, и это совсем не так, как работает @LinkingObjects?

Еще одна вещь, которая не совсем понятна - как вы заметите, gridnode является приватным членом класса PassPoint. Как тогда я могу создать аннотацию @LinkingObjects("gridnode") в своем классе GridNode без компилятора, жалующегося на то, что я пытаюсь получить доступ к члену, который не виден снаружи класса PassPoint?

Я бы очень ценю любую помощь и указатели здесь.

1 Ответ

1 голос
/ 13 января 2020

Чтение между строк. Я пришел к выводу, что выполнение этого запроса не только вызовет GridNode, который мне нужен, но и выполнит неявный запрос

Нет. Не совсем.

Как указано в документации Realm здесь :

Все выборки (включая запросы) в Realm ленивы, и данные никогда не копируются.

Это означает, что простой случай определения запроса делает именно это - он определяет его. Но он не оценивает / не выполняет запрос, пока пользователь не запросит его. Следовательно, объект с полем запроса (например, полем LinkingObjects) предоставляет простой метод, с помощью которого пользователь может выполнить запрос, но не выполняет его автономно только потому, что сам объект загружен. Он запускается только при выполнении вызова findFirst или findAll (или аналогичного).

Так что, если вы фактически никогда не получаете доступ к полю GridNode.passpoints, оно никогда не выполняется.

Вы можете доказать это себе с помощью простого эксперимента: -

  1. Получить GridNode из Царства без связанных PassPoint.
  2. Доступ к поле связывания объектов и убедитесь, что оно пустое.
  3. Добавьте новый Passpoint в область со ссылкой на тот же GridNode.
  4. Повторно протестируйте поле связывания объектов того же объекта Вы получили на шаге 1, и вы должны увидеть, что теперь в результат запроса входит новый Passpoint.

Что касается вашего второго вопроса, простой ответ заключается в том, что применяется уровень защиты полей модели только для Java моделей ваших данных; он не применяется к базовым моделям областей.

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