我正在开发一个Android播客应用程序,它将数据存储在一个Room数据库中。数据库存储播客和流行病。以下是各自使用的类:
Episode.kt
@Entity(tableName = "episodes", indices = arrayOf(Index(value = ["media_id"], unique = true)))
data class Episode (
@PrimaryKey
@ColumnInfo (name = "media_id")
val mediaId: String,
@ColumnInfo (name = "title")
val title: String,
@ColumnInfo (name = "publication_date")
val publicationDate: Date,
// used to define relation between episode and podcast
@ColumnInfo (name = "episode_remote_podcast_feed_location")
val episodeRemotePodcastFeedLocation: String,
...)
{...}
Podcast.kt
@Entity(tableName = "podcasts", indices = arrayOf(Index(value = ["remote_podcast_feed_location"], unique = true)))
data class Podcast(
@PrimaryKey
@ColumnInfo (name = "remote_podcast_feed_location") val remotePodcastFeedLocation: String,
@ColumnInfo (name = "name") val name: String
...)
{ ... }
此外,我还创建了一个包装类,它定义了播客和插曲之间的关系。
PodcastWrapper.kt
data class PodcastWrapper(
@Embedded
val data: Podcast,
@Relation(parentColumn = "remote_podcast_feed_location", entityColumn = "episode_remote_podcast_feed_location")
val episodes: List<Episode>)
{ ... }
为了将所有的Podcasts与它们的所有剧集组合在一起,我使用下面的DAO,它将返回一个List
of PodcastWrapper
作为LiveData
。效果很好。
PodcastDao.kt
@Dao
interface PodcastDao {
@Transaction
@Query("SELECT * FROM podcasts")
fun getAllPodcastsLiveData(): LiveData<List<PodcastWrapper>>
}
我的问题
播客经常有100+的插曲。我只需要观察最后10集(使用LiveData)。我需要一个DAO
,返回所有的播客组合在一起的与最近的10集-理想的LiveData<List<PodcastWrapper>>
。我不知道那是怎么可能的。有什么想法吗?
发布于 2020-09-24 19:09:13
没有简单的方法,房间里的关系部不支持你想要的东西。尽管如此,我还是可以建议你尝试一些方法(我不确定它会起作用,但你可以试试):
TopEpisodesDataView
。它的身体应该是这样的:@DatabaseView("select ...") <-- There you should put query that returns only last 10 episodes for each podcast
data class TopEpisodesDataView(
@Embedded
val episode: Episode
)
Episode
表替换为TopEpisodesDataView
:data class PodcastWrapper(
@Embedded
val data: Podcast,
@Relation(parentColumn = "remote_podcast_feed_location", entityColumn = "episode_remote_podcast_feed_location")
val episodes: List<TopEpisodesDataView>)
因此,似乎唯一的问题是如何在步骤1中获得所需的查询。为此,尝试遵循下一个Stackoverflow的链接- link1或link2 (或类似的)。
但是.,即使它有效,我也不确定结果中的事件是否会按时间顺序排序,因为Room的关系并不能保证子表的行的顺序(所以您可以得到最后10集,但首先是episode23,然后是第21集,然后是第29集等等)。因此,您的选择可能是手动完成所有操作(连接表、循环结果并使其按需要工作)。
发布于 2020-09-26 15:00:59
sergiy建议的解决方案效果很好。为了完整起见,这里我用来实现建议的代码:
EpisodeMostRecentView.kt (新)
@DatabaseView("SELECT * FROM episodes e WHERE ( SELECT count(*) from episodes e1 WHERE e1.episode_remote_podcast_feed_location = e.episode_remote_podcast_feed_location AND e1.publication_date >= e.publication_date ) <= 5")
data class EpisodeMostRecentView (
@Embedded
val data: Episode)
{ ... }
用于创建上述DatabaseView
的查询返回(较小的) Episode
s列表--仅为每个Podcast
返回最近的5个(由episode_remote_podcast_feed_location
标识)。
SELECT *
FROM episodes e
WHERE (
SELECT count(*)
from episodes e1
WHERE
e1.episode_remote_podcast_feed_location = e.episode_remote_podcast_feed_location
AND e1.publication_date >= e.publication_date
) <= 5
PodcastDatabase.kt (变更)
添加views = arrayOf(EpisodeMostRecentView::class)
@Database(entities = arrayOf(Podcast::class, Episode::class), views = arrayOf(EpisodeMostRecentView::class),version = 1)
abstract class PodcastDatabase : RoomDatabase() {
abstract fun podcastDao(): PodcastDao
...
}
PodcastWithRecentEpisodesWrapper.kt (新)
使用List<EpisodeMostRecentView>
,而PodcastWrapper
使用List<Episode>
data class PodcastWithRecentEpisodesWrapper(
@Embedded
val data: Podcast,
@Relation(parentColumn = "remote_podcast_feed_location", entityColumn = "episode_remote_podcast_feed_location")
val episodes: List<EpisodeMostRecentView>)
{ ... }
PodcastDao.kt (变更)
LiveData<List<PodcastWithRecentEpisodesWrapper>>
而不是LiveData<List<PodcastWrapper>>
@Dao
interface PodcastDao {
@Transaction
@Query("SELECT * FROM podcasts")
fun getFiveMostRecentPodcastsLiveData(): LiveData<List<PodcastWithRecentEpisodesWrapper>>
}
发布于 2020-09-23 11:28:18
您必须通过使用诸如ORDER或LIMIT之类的查询术语来实现查询。
@Transaction
@Query("SELECT * FROM "+ Constants.TABLE_NAME_TRANSLATION+" ORDER BY id DESC LIMIT :limit ")
LiveData<List<TranslationHistory>> getLimitList(int limit);
https://stackoverflow.com/questions/64025864
复制相似问题