Как применить условие к отношению или как правильно обрабатывать запросы JOIN с предложением WHERE в Room? - PullRequest
2 голосов
/ 04 апреля 2019

Пожалуйста, потерпите меня, я новичок в компонентах архитектуры и Android в целом.Мой вопрос похож на этот вопрос , но, к сожалению, принятый ответ не работает.У меня есть пример отношения один ко многим, как в этот ответ .В моем примере базы данных есть две таблицы USERS и PETS, как показано на следующих изображениях:

12

Допустим, я хочу получить список пользователей, содержащий список их питомцев.сгруппированы по идентификатору пользователя только с домашними животными моложе 5. Результат должен выглядеть следующим образом (псевдокод):

{uId: 2, [Pet3, Pet4];uId: 4, [Pet6, Pet7];}

Другое требование состоит в том, что Dao должен возвращать список как объект LiveData, потому что я использую архитектуру MVVM и хочу, чтобы он был осведомлен о жизненном цикле и наблюдался.

При этих требованиях UserDao будет выглядеть следующим образом:

@Dao
interface UserDao {

    @Insert
    void insert(User user);

    @Transaction
    @Query("SELECT USERS.uId, PETS.pId , PETS.userId, PETS.age " + 
    "FROM USERS INNER JOIN PETS ON PETS.userId = USERS.uId " +
    "WHERE PETS.age < 5 " +
    "GROUP BY USERS.uId")
    LiveData<List<UserWithPets>> getUserPets();

}

Пользователь Объект:

@Entity
public class User {
    @PrimaryKey
    public int id; // User id
}

Pet Entity:

@Entity
public class Pet {
    @PrimaryKey
    public int id;     // Pet id
    public int userId; // User id
    public int age;
}

Теперь проблема: как мне спроектировать UserWithPets, чтобы комната понимала его и отображала курсор так, как я хочу?Вот что я попробовал до сих пор:

Подход 1:

На мой взгляд, наиболее удобным способом было бы использовать отношение, как в приведенном ниже POJO.

UserWithPets POJO:

public class UserWithPets {
    @Embedded
    public User user;

    @Relation(parentColumn = "id", entityColumn = "userId", entity = Pet.class)
    public List<Pet> pets; 

}

К сожалению, функция назначения условия для отношения еще не реализована в Google.Таким образом, мы всегда получаем полный список домашних животных для каждого пользователя, которому принадлежит домашнее животное моложе 5. Надеемся, что это будет возможно в ближайшее время, так как запрос функции уже назначен здесь и здесь .

Заявление от Google из этого запроса функции: «Мы планируем реализовать некоторую логику переписывания запросов, чтобы исправить это, не для 2.1, но, надеюсь, в 2.2, где мы сосредоточимся больше на отношениях."

Подход 2:

Другой вариант будет встраивать как пользователь, так и питомец, как:

public class UserWithPets {
    @Embedded
    public User user;

    @Embedded
    public Pet pet;

}

Это тоже не работает, потому что теперь мы получаем только 1Пэт на пользователя.

Подход 3:

Этот ответ предлагает просто создать объединенный класс, который расширяется от пользователя, как:

public class UserWithPets extends User {

    @Embedded(prefix = "PETS_")
    List<Pet> pets = new ArrayList<>();
}

Iпытался во многих отношениях, с конструктором и без, но я не могу заставить его работать.он всегда выдает такие ошибки, как «Сущности и Pojos должны иметь открытый открытый конструктор. У вас может быть пустой конструктор или конструктор, параметры которого соответствуют полям (по имени и типу). - java.util.List» или Запрос возвращает несколько столбцов.... которые не используются UserWithPets.Так что любые советы приветствуются.

Подход 4:

Просто сделайте два запроса и объедините результаты.Как бы я сделал это, используя LiveData?Где должна быть сделана операция соединения?Я не могу сделать это в Activity, дело не в паттерне MVVM.И не в хранилище или в viewmodel, так как LiveData является неизменным.Или есть другой способ?

Каким было бы рабочее решение для получения результата с вышеуказанными требованиями?

...