Android Kotlin 中的数据库存储库比较 and/or 更新?
Database repository comparison and/or update in Android Kotlin?
我是 android 编程新手,想尝试学习最佳实践。我正在构建的第一个应用程序是一个播客应用程序,用于显示来自 rss 提要的播客并播放它们。到目前为止,我是工作,但我知道我可以让它工作得更好。
我正在使用带有存储库模式的房间数据库,这可能有点矫枉过正,因为如果我只是要在启动时重新解析提要,我可能不需要在应用程序死亡时保留播客列表.在我的存储库 class 中,我正在调用我的 FetchRSS class 在 init{ }
块中进行网络调用,其中 returns a List<Podcast>
.
我知道我做错了什么。
在我的 PodcastDao 中,我必须使用 @Insert(onConflict = OnConflictStrategy.REPLACE)
因为数据库已经存在并且我收到关于重复主键 ID 的 SQL 错误 1555。从逻辑上讲,最好检查一下要添加的条目是否已经在数据库中,但我不确定如何去做。或者,不合逻辑地,在应用程序死亡时清除数据库,但为什么要费心使用数据库呢。理想情况下,我希望有滑动更新功能(即使 RSS 每周最多只更新两次),但我不确定如何最好地做到这一点。
如果有人对此有任何改进的想法,或者有一本学习的好书 android,我会洗耳恭听。
非常感谢所有花时间看这篇文章的人!
PodcastDao.kt
@Dao
interface PodcastDao {
@Query("SELECT * FROM podcast") // get everything from the database
fun getPodcasts(): LiveData<List<Podcast>>
@Query("SELECT * FROM podcast WHERE id=(:id)") // get the specific podcast
fun getPodcast(id: String): LiveData<Podcast?>
// @Insert(onConflict = OnConflictStrategy.REPLACE)
// fun addPodcasts(podcasts: LiveData<List<Podcast>>)
// this causes a build error with the generated PodcastDao.java file
// logcat error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addPodcast(podcast: Podcast)
}
PodcastRepository.kt
class PodcastRepository private constructor(context: Context) {
private lateinit var podcasts: List<Podcast>
init {
CoroutineScope(Dispatchers.Main).launch {
podcasts = FetchRSS().fetchRss() // executes on Dispatchers.IO and returns parsed rss List<Podcast>
// this seems silly to add them one at a time, especially since the list is rather large
for (pod in podcasts) {
addPodcast(pod)
}
//it seems a better choice to dump the full list into the database at once
//however I can't figure out how to put the List<Podcast> into a LiveData<List<Podcast>> object
//or maybe I'm misunderstanding something about LiveData<>
//addPodcasts(podcasts)
}
}
suspend fun addPodcast(podcast: Podcast){
withContext(Dispatchers.IO){
podcastDao.addPodcast(podcast)
}
// this needs to receive the LiveData<List<Podcast>>, or a List<Podcast> and cram it into LiveData<>?
// suspend fun addPodcasts(podcasts: LiveData<List<Podcast>>) {
// withContext(Dispatchers.IO){
// podcastDao.addPodcasts(podcasts)
// }
// }
}
fun addPodcasts(podcasts: LiveData<List<Podcast>>)
应该是
fun addPodcasts(podcasts: <List<Podcast>>)
因此,现在您可以从您的存储库中调用 podcastDao.addPodcasts(podcasts)
(其中 podcasts
的类型为 List<Podcast>>
),而不是通过 for 循环将它们一一插入。
您不能将 LiveData 插入 Room,只能插入标有 @Entity
的对象。但是,您可以查询 return 带有这些实体列表的 LiveData。您也可以 return 只是一个列表。
我是 android 编程新手,想尝试学习最佳实践。我正在构建的第一个应用程序是一个播客应用程序,用于显示来自 rss 提要的播客并播放它们。到目前为止,我是工作,但我知道我可以让它工作得更好。
我正在使用带有存储库模式的房间数据库,这可能有点矫枉过正,因为如果我只是要在启动时重新解析提要,我可能不需要在应用程序死亡时保留播客列表.在我的存储库 class 中,我正在调用我的 FetchRSS class 在 init{ }
块中进行网络调用,其中 returns a List<Podcast>
.
我知道我做错了什么。
在我的 PodcastDao 中,我必须使用 @Insert(onConflict = OnConflictStrategy.REPLACE)
因为数据库已经存在并且我收到关于重复主键 ID 的 SQL 错误 1555。从逻辑上讲,最好检查一下要添加的条目是否已经在数据库中,但我不确定如何去做。或者,不合逻辑地,在应用程序死亡时清除数据库,但为什么要费心使用数据库呢。理想情况下,我希望有滑动更新功能(即使 RSS 每周最多只更新两次),但我不确定如何最好地做到这一点。
如果有人对此有任何改进的想法,或者有一本学习的好书 android,我会洗耳恭听。 非常感谢所有花时间看这篇文章的人!
PodcastDao.kt
@Dao
interface PodcastDao {
@Query("SELECT * FROM podcast") // get everything from the database
fun getPodcasts(): LiveData<List<Podcast>>
@Query("SELECT * FROM podcast WHERE id=(:id)") // get the specific podcast
fun getPodcast(id: String): LiveData<Podcast?>
// @Insert(onConflict = OnConflictStrategy.REPLACE)
// fun addPodcasts(podcasts: LiveData<List<Podcast>>)
// this causes a build error with the generated PodcastDao.java file
// logcat error: Type of the parameter must be a class annotated with @Entity or a collection/array of it.
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun addPodcast(podcast: Podcast)
}
PodcastRepository.kt
class PodcastRepository private constructor(context: Context) {
private lateinit var podcasts: List<Podcast>
init {
CoroutineScope(Dispatchers.Main).launch {
podcasts = FetchRSS().fetchRss() // executes on Dispatchers.IO and returns parsed rss List<Podcast>
// this seems silly to add them one at a time, especially since the list is rather large
for (pod in podcasts) {
addPodcast(pod)
}
//it seems a better choice to dump the full list into the database at once
//however I can't figure out how to put the List<Podcast> into a LiveData<List<Podcast>> object
//or maybe I'm misunderstanding something about LiveData<>
//addPodcasts(podcasts)
}
}
suspend fun addPodcast(podcast: Podcast){
withContext(Dispatchers.IO){
podcastDao.addPodcast(podcast)
}
// this needs to receive the LiveData<List<Podcast>>, or a List<Podcast> and cram it into LiveData<>?
// suspend fun addPodcasts(podcasts: LiveData<List<Podcast>>) {
// withContext(Dispatchers.IO){
// podcastDao.addPodcasts(podcasts)
// }
// }
}
fun addPodcasts(podcasts: LiveData<List<Podcast>>)
应该是
fun addPodcasts(podcasts: <List<Podcast>>)
因此,现在您可以从您的存储库中调用 podcastDao.addPodcasts(podcasts)
(其中 podcasts
的类型为 List<Podcast>>
),而不是通过 for 循环将它们一一插入。
您不能将 LiveData 插入 Room,只能插入标有 @Entity
的对象。但是,您可以查询 return 带有这些实体列表的 LiveData。您也可以 return 只是一个列表。