首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android :寻找限制@Embedded列表中元素数量的DAO

Android :寻找限制@Embedded列表中元素数量的DAO
EN

Stack Overflow用户
提问于 2020-09-23 10:23:57
回答 3查看 607关注 0票数 2

我正在开发一个Android播客应用程序,它将数据存储在一个Room数据库中。数据库存储播客和流行病。以下是各自使用的类:

Episode.kt

代码语言:javascript
运行
复制
@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

代码语言:javascript
运行
复制
@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

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
@Dao
interface PodcastDao {

    @Transaction
    @Query("SELECT * FROM podcasts")
    fun getAllPodcastsLiveData(): LiveData<List<PodcastWrapper>>

}

我的问题

播客经常有100+的插曲。我只需要观察最后10集(使用LiveData)。我需要一个DAO,返回所有的播客组合在一起的与最近的10集-理想的LiveData<List<PodcastWrapper>>。我不知道那是怎么可能的。有什么想法吗?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-09-24 19:09:13

没有简单的方法,房间里的关系部不支持你想要的东西。尽管如此,我还是可以建议你尝试一些方法(我不确定它会起作用,但你可以试试):

  1. 添加DatabaseView (您可以阅读链接中的内容),比如TopEpisodesDataView。它的身体应该是这样的:
代码语言:javascript
运行
复制
@DatabaseView("select ...") <-- There you should put query that returns only last 10 episodes for each podcast
data class TopEpisodesDataView(
    @Embedded
    val episode: Episode
)
  1. 在您的关系中,您应该将Episode表替换为TopEpisodesDataView
代码语言:javascript
运行
复制
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的链接- link1link2 (或类似的)。

但是.,即使它有效,我也不确定结果中的事件是否会按时间顺序排序,因为Room的关系并不能保证子表的行的顺序(所以您可以得到最后10集,但首先是episode23,然后是第21集,然后是第29集等等)。因此,您的选择可能是手动完成所有操作(连接表、循环结果并使其按需要工作)。

票数 1
EN

Stack Overflow用户

发布于 2020-09-26 15:00:59

sergiy建议的解决方案效果很好。为了完整起见,这里我用来实现建议的代码:

EpisodeMostRecentView.kt (新)

代码语言:javascript
运行
复制
@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的查询返回(较小的) Episodes列表--仅为每个Podcast返回最近的5个(由episode_remote_podcast_feed_location标识)。

代码语言:javascript
运行
复制
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)

代码语言:javascript
运行
复制
@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>

代码语言:javascript
运行
复制
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>>

代码语言:javascript
运行
复制
@Dao
interface PodcastDao {

    @Transaction
    @Query("SELECT * FROM podcasts")
    fun getFiveMostRecentPodcastsLiveData(): LiveData<List<PodcastWithRecentEpisodesWrapper>>

}
票数 2
EN

Stack Overflow用户

发布于 2020-09-23 11:28:18

您必须通过使用诸如ORDER或LIMIT之类的查询术语来实现查询。

代码语言:javascript
运行
复制
@Transaction
@Query("SELECT * FROM "+ Constants.TABLE_NAME_TRANSLATION+" ORDER BY id DESC LIMIT :limit  ")
 LiveData<List<TranslationHistory>> getLimitList(int limit);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64025864

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档