Использование аннотации @Relation. Я могу запросить отношение «один ко многим», используя следующее:
@Dao
public interface PostDao {
@Query("SELECT * FROM post")
List<PostWithComments> getPostWithComments();
}
Вот сущности
@Entity
public class Post {
@PrimrayKey
private int id;
private String title;
private String content;
}
@Entity
public class Comment {
@PrimrayKey
private int id;
private int post_id;
private String content;
private String status;
}
public class PostWithComments {
@Embedded
public Post post;
@Relation(parentColumn = "id", entityColumn = "post_id", entity = Comment.class)
public List<Comment> comments;
}
Я хотел бы получить все сообщения, которые имеют комментарий с status = approved
, но я не совсем уверен, как комната справляется с этим. Я пробовал следующее:
@Dao
public interface PostDao {
@Query("SELECT * FROM post INNER JOIN comment ON post.id = comment.post_id WHERE comment.status = 'approved'")
List<PostWithComments> getPostWithComments();
}
У меня есть дубликаты в результатах. Каждый пост появляется несколько раз в List<PostWithComments>
результатах.
Обновлять:
После прочтения сгенерированного кода в PostDao_Impl.java
кажется, что Room выполняет подзапрос для получения отношения.
Сначала он выполняет запрос в аннотации @Query
из метода getPostWithComments
, а затем генерирует подзапрос для отношения для заполнения List<Comment>
SELECT id, post_id, title, content FROM comment WHERE post_id IN (
и некоторая другая логика, и, похоже, нет способа изменить сгенерированный подзапрос.
Есть ли другой способ сделать это?
@uan это то, что я делаю, но в идеале я должен иметь возможность фильтровать их в запросе.
Не проверено, но вы можете попробовать это...
public class PostWithComments {
@Embedded
public Post post;
@Embedded
public Comment comment;
}
@Dao
public interface PostWithCommentsDao {
@Query("SELECT post.*, comment.* FROM post LEFT JOIN comment ON post.id=comment.post_id where comment.status = 'approved'")
List<PostWithComments> getPostWithComments();
}
Как это должно работать? Каждый пост имеет несколько комментариев, а не один. Объект PostWithComments должен иметь один пост и список комментариев.
С @Relation вы можете использовать @DatabaseView
@DatabaseView("SELECT * FROM comments WHERE status = 'approved'")
public class ApprovedComment {
@Embedded
Comment comment;
}
Класс PostWithComments
public class PostWithComments {
@Embedded
public Post post;
@Relation(parentColumn = "id", entityColumn = "post_id", entity = ApprovedComment.class)
public List<ApprovedComment> comments;
}
ДАО
@Dao
public interface PostWithCommentsDao {
@Query("SELECT * FROM post")
List<PostWithComments> getPostWithComments();
}
Вам также необходимо обновить класс базы данных, который расширяет RoomDatabase, и вам может потребоваться обновить версию.
@Database(entities = {Post.class, Comment.class}, views = {ApprovedComment.class}, version = 1)
public abstract class MyDatabase extends RoomDatabase
Отличный ответ, отлично работает. Обратите внимание, что это также способ использования предложения Сортировать по для дочерних сущностей в отношении: добавьте порядок в запрос DatabaseView.
А пока, может быть, вы сможете отфильтровать полученные комментарии.