Есть ли способ контролировать порядок дочерних объектов при использовании отношений «один ко многим»?

Согласно https://developer.android.com/training/data-storage/room/relationships

У нас могут быть отношения один ко многим

public class UserWithPlaylists {
    @Embedded public User user;
    @Relation(
         parentColumn = "userId",
         entityColumn = "userCreatorId"
    )
    public List<Playlist> playlists;
}

@Transaction
@Query("SELECT * FROM User")
public List<UserWithPlaylists> getUsersWithPlaylists();

В сущности User и Playlist мы добавили столбец с именем sort_key.

Цель в том, что когда мы выполняем запрос, мы можем сделать следующее

@Transaction
@Query("SELECT * FROM User order by sort_key")
public List<UserWithPlaylists> getUsersWithPlaylists();

Мы можем контролировать порядок List<UserWithPlaylists>.

Но как насчет List<Playlist> playlists дочерней сущности?

Как мы можем определить собственный запрос для дочерней сущности Playlist, чтобы мы могли контролировать порядок List<Playlist> playlists?


person Cheok Yan Cheng    schedule 25.05.2020    source источник


Ответы (3)


Как мы можем определить собственный запрос для списка воспроизведения дочерней сущности, чтобы мы могли контролировать порядок списков воспроизведения List?

Боюсь, здесь нет нестандартного способа.

Используя аннотацию @Relation, все, что у вас есть, это:

  • 5 параметров аннотации (associateBy, entity, entityColumn, parentColumn, projection. Ни один из них не влияет на порядок элементов дочерней таблицы)

  • Под капотом Relation Room используется два запроса — сначала вы явно пишете в своем DAO

SELECT * FROM User order by sort_key

и еще один - для выборки данных из дочерней таблицы (на основе типа результата запроса и параметров @Relation):

SELECT * FROM PlayList WHERE userCreatorId IN (<List of users id from the first query>)

Этот запрос создается автоматически, и в аннотации @Relation нет возможности изменить порядок элементов в нем.

Конечно, после получения этого «неупорядоченного» результата вы можете добавить некоторую постобработку, чтобы добиться желаемого вручную.

person sergiy tikhonov    schedule 25.05.2020

Я не уверен, что можно добавить @Query в поле, но я уверен, что вы можете использовать определенную коллекцию для выполнения заказа. Вот шаги:

  1. Сделайте сущность Playlist реализующей интерфейс Comparable, затем определите метод compareTo после атрибута sort_key.

  2. Вместо списка в объекте UserWithPlaylists используйте SortedSet или TreeSet, эта конкретная коллекция возвращает элементы, упорядоченные с использованием естественного порядка или компаратора.

person Kenany    schedule 30.05.2020

Вы можете реализовать эту функцию двумя способами:

1) Вы можете использовать аннотацию @Sort, специфичную для Hibernate, для выполнения сортировки в памяти (т.е. не в базе данных), используя естественную сортировку или сортировку с использованием предоставленного вами компаратора. Например, предположим, что у меня есть вспомогательный класс MyComparator, который реализует Comparator. Вспомогательный класс может помочь вам отсортировать по sort_key. Вы можете изменить коллекцию плейлистов следующим образом:

@org.hibernate.annotations.Sort(type = SortType.COMPARATOR, comparator = MyComparator)
public Set<Playlist> playlists;

@Sort выполнит сортировку в памяти после извлечения коллекции из базы данных.

2) Вы можете использовать аннотацию @OrderBy hibernate, которая позволяет указать фрагмент SQL, описывающий, как выполнять сортировку.

@org.hibernate.annotations.OrderBy("sort_key")
 public Set<Playlist> playlists;

Надеюсь, это поможет..!!

person karan007    schedule 03.06.2020