我现在正试图弄清楚如何插入、更新或删除播放列表
播放列表是一个 POJO,旨在(当与 Embedded/@Relation 一起使用时)用于从数据库中提取数据,而不是用于修改数据库中的数据。即这是一种方式。
但是,如果它不是数据类而是类(我认为),那么您可以添加函数来执行此类操作。例如
class Playlist {
@Embedded
var playlistInfo: PlaylistInfo? = null
@Relation(
parentColumn = "playlistId",
entityColumn = "songId",
associateBy = Junction(PlaylistSongCrossRef::class)
)
var songs: MutableList<Song>? = null
fun deletePlayList(dao: AllDao, playlist: Playlist, deleteOrphanedSongs: Boolean = false) {
val currentPlaylistInfo: PlaylistInfo? = playlist.playlistInfo
if (currentPlaylistInfo != null) {
dao.deleteByPlayListId(currentPlaylistInfo.playlistId)
dao.delete(currentPlaylistInfo)
if (deleteOrphanedSongs) {
dao.deleteManySongs(playlist.songs!!)
}
}
}
}
您可以使用提取的播放列表执行的操作是删除播放列表和歌曲,例如:-
@Delete()
fun deletePlayListInfoAndSongs(playlistInfo: PlaylistInfo, songs: List<Song>): Int
- 即使用提取的播放列表,您将拥有嵌入式播放列表信息和相关的歌曲
但是,请注意,上述内容不会删除关联的PlaylistSongCrossRef行,因此您最终会得到可能有问题的孤儿。
您可能希望考虑定义外键并使用 onDelete 和/或 onUpdate 操作进行 CASCADE 删除。
示例/演示
以下是基于您的实体(为方便起见将歌曲路径更改为字符串而不是 URI)和上述播放列表类的示例。
供您考虑的道是:-
@Dao
interface AllDao {
@Insert
fun insert(playlistInfo: PlaylistInfo): Long
@Insert
fun insertManyPlaylistInfos(playlistInfoList: List<PlaylistInfo>): LongArray
@Insert
fun insert(song: Song): Long
@Insert
fun insertManySongs(songList: List<Song>): LongArray
@Insert
fun insert(playlistSongCrossRef: PlaylistSongCrossRef): Long
@Insert
fun insertManyPlaylistSongCrossrefs(playlistSongCrossRefList: List<PlaylistSongCrossRef>): LongArray
@Query("SELECT * FROM song")
fun getAllSongs(): List<Song>
@Query("SELECT * FROM song WHERE song.name = :songname LIMIT 1")
fun getFirstSongByName(songname: String): Song
@Query("SELECT * FROM playlistInfo")
fun getAllPlaylistInfos(): List<PlaylistInfo>
@Query("SELECT * FROM playlistinfo WHERE playlistinfo.name = :playlistname LIMIT 1")
fun getFirstPlaylistInfoByName(playlistname: String): PlaylistInfo
@Query("SELECT * FROM playlistsongcrossref")
fun getAllPlaylistSongCrossRefs(): List<PlaylistSongCrossRef>
@Transaction
@Query("SELECT * FROM playlistinfo")
fun getAllPlaylists(): List<Playlist>
@Query("SELECT count(*) FROM song")
fun getNumberOfSongs(): Long
@Query("SELECT count(*) FROM playlistinfo")
fun getNumberOfPlaylistInfos(): Long
@Query("SELECT count(*) FROM playlistsongcrossref")
fun getNumberOfSongsInPlaylists(): Long
@Update
fun update(song: Song)
@Update
fun update(playlistInfo: PlaylistInfo)
/* Suggested NEVER to use */
@Update
fun update(playlistSongCrossRef: PlaylistSongCrossRef)
@Delete
fun delete(playlistInfo: PlaylistInfo): Int
@Delete()
fun delete(song: Song): Int
@Delete
fun deleteManySongs(songs: List<Song>): Int
@Delete
fun delete(playlistSongCrossRef: PlaylistSongCrossRef): Int
@Delete()
fun deletePlayListInfoAndSongs(playlistInfo: PlaylistInfo, songs: List<Song>): Int
//@Delete
//fun deletePlayListInfoAndSongs(playlist: Playlist): Int
@Query("DELETE FROM playlistsongcrossref WHERE playlistId = :playlistId")
fun deleteByPlayListId(playlistId: Long): Int
@Query("DELETE FROM playlistsongcrossref WHERE playlistId = :playlistId AND songId = :songId")
fun deleteSongFromPlaylist(playlistId: Long, songId: Long)
}
也许在一个显示更新、删除和插入示例的活动中考虑以下内容:-
class MainActivity : AppCompatActivity() {
private val TAG = "PLDBINFO"
lateinit var db: TheDatabase
lateinit var dao: AllDao
val songList = listOf<Song>(
Song(1L,"My Song","x"),
Song(2L,"Your Song","Y"),
Song(3L,"Her Song","Z"),
Song(4L,"His Song","A"),
Song(5L,"Their Song","B"),
Song(6L,"Nobody's Song","C")
)
val playlistInfoList = listOf<PlaylistInfo>(
PlaylistInfo("My PlayList"),
PlaylistInfo("Your PlayList"),
PlaylistInfo("Her PlayList")
)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// Get the Database and the Dao
db = Room.databaseBuilder(this,TheDatabase::class.java,"playlist.db")
.allowMainThreadQueries()
.build()
dao = db.getDao()
// Add all the Playlist and Songs and add every Song to all the Playlists
// ONLY IF no data exists
if (dao.getNumberOfPlaylistInfos() + dao.getNumberOfPlaylistInfos() + dao.getNumberOfSongsInPlaylists() < 1) {
dao.insertManySongs(songList)
dao.insertManyPlaylistInfos(playlistInfoList)
for(p: PlaylistInfo in dao.getAllPlaylistInfos()) {
for(s: Song in dao.getAllSongs()) {
dao.insert(PlaylistSongCrossRef(p.playlistId,s.songId))
}
}
}
// Write the counts to the Log
logStats()
// Extract All Core Objects
var allPlaylistInfos = dao.getAllPlaylists()
var allSongs = dao.getAllSongs()
var allPlaylists = dao.getAllPlaylists()
var allPlaylistSongCrossRefs = dao.getAllPlaylistSongCrossRefs()
Log.d(TAG,"Extracted PlaylistInfos = ${allPlaylistInfos.size} " +
"Extacted Songs = ${allSongs.size} " +
"Extracted Playlists = ${allPlaylists.size} " +
"Extracted PlaylistSongCrossRefs = ${allPlaylistSongCrossRefs.size}"
)
// Add a new song and also put it into the My PlayList playlist
dao.insert(PlaylistSongCrossRef(dao.getFirstPlaylistInfoByName("My PlayList").playlistId,dao.insert(Song(10L,"Bert's Song","D"))))
// ASame as above BUT using function getPlaylistInfoIdByName below that gets the ID
dao.insert(PlaylistSongCrossRef(getPlaylistInfoIdByName("My PlayList"),dao.insert(Song(20L,"Mary's Song","E"))))
//
var otherPlTodelete = dao.getFirstPlaylistInfoByName("Her PlayList")
for(pl: Playlist in allPlaylistInfos) {
/* Best to not use this
if (pl.playlistInfo!!.playlistId == plToDelete.playlistId ) {
dao.deletePlayListInfoAndSongs(pl.playlistInfo!!,pl.songs!!)
}
*/
if (pl.playlistInfo!!.playlistId == otherPlTodelete.playlistId) {
pl.deletePlayList(dao,pl,false) /* best to only use false */
}
}
var playlistToUpdate = dao.getFirstPlaylistInfoByName("Your PlayList")
playlistToUpdate.name = "PlayList that is for Your but it was Your PlayList"
dao.update(playlistToUpdate)
logStats()
}
private fun logStats() {
Log.d(TAG," Playlist Count = " + dao.getNumberOfPlaylistInfos()
+ " Song Count = " + dao.getNumberOfSongs()
+ " Song/Playlist count = " + dao.getNumberOfSongsInPlaylists()
)
}
private fun getSongIdByName(songName: String): Long {
return dao.getFirstSongByName(songName).songId
}
private fun getPlaylistInfoIdByName(playlistInfoName: String): Long {
return dao.getFirstPlaylistInfoByName(playlistInfoName).playlistId
}
}
首先,如果不存在数据(通过查询获取行数的示例),则添加 3 个播放列表和 6 首歌曲,每个播放列表包含所有歌曲(因此 18 个交叉引用行)。
然后统计信息(每个表的行输出到日志)。
然后提取所有类型(PlaylistInfo's、Song's、PlaylistSongCrossref's 和 PlayList's)并显示计数(应与统计数据相符)。
然后,两首新歌曲不仅作为歌曲添加,而且还添加到名为“我的播放列表”的播放列表中
根据名称找到名为“Her PlayList”的播放列表信息(又名播放列表)。它与 PlayListSongCrossRef 一起被删除,因此不会通过 Playlists 类中的函数留下孤立的歌曲。
然后名为“Your PlayList”的播放列表被命名为“PlayList that is for Your but it was Your PlayList”。