Slick 3 多对多关系:如何获取 table 的所有元素及其关系(如果存在)?
Slick 3 many to many relations: how to get all the element of a table and their relations if they exist?
我正在使用 Slick 3 和 Play! 2.4 并且我有一个非常常见的问题,但我无法解决。
我有一个 table playlist
可以在关系 table playlistsTracks
的帮助下链接到某些曲目。我希望能够获得所有播放列表及其曲目关系和曲目。我的问题是,如果他们没有任何关系,我就无法获取播放列表。
这是 3 个 table:
class Playlists(tag: Tag) extends Table[Playlist](tag, "playlists") {
def id = column[Long]("playlistid", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id.?, name) <> ((Playlist.apply _).tupled, Playlist.unapply)
}
class PlaylistsTracks(tag: Tag) extends Table[PlaylistTrack](tag, "playliststracks") {
def playlistId = column[Long]("playlistid")
def trackId = column[UUID]("trackid")
def trackRank = column[Double]("trackrank")
def * = (playlistId, trackId, trackRank) <> ((PlaylistTrack.apply _).tupled, PlaylistTrack.unapply)
def aFK = foreignKey("playlistId", playlistId, playlists)(_.id, onDelete = ForeignKeyAction.Cascade)
def bFK = foreignKey("trackId", trackId, tracks)(_.uuid, onDelete = ForeignKeyAction.Cascade)
}
class Tracks(tag: Tag) extends Table[Track](tag, "tracks") {
def uuid = column[UUID]("trackid", O.PrimaryKey)
def title = column[String]("title")
def * = (uuid, title) <> ((Track.apply _).tupled, Track.unapply)
}
目前获取播放列表的代码片段如下所示:
val query = for {
playlist <- playlists
playlistTrack <- playlistsTracks if playlistTrack.playlistId === playlist.id
track <- tracks if playlistTrack.trackId === track.uuid
} yield (playlist, playlistTrack, track)
db.run(query.result) map { println }
它打印出类似 Vector(Playlist, PlaylistTrack, Track)
的内容(我想要的),但我只得到具有关系的播放列表,而不是得到所有播放列表,即使是我想要的没有关系的播放列表。
我尝试了很多方法,例如使用 join(或 joinFull、joinLeft、joinRight...)但都没有成功,不幸的是很难找到一些不仅关系非常简单的示例项目。
您需要在 Playlists 和 PlaylistTracks 之间使用左连接 table 并在 PlaylistTracks 和 Tracks 之间使用 inner join。
该示例中缺少一些内容,因此我实际上无法编译以下内容,但我认为您可以尝试类似的操作:
val query = for {
(playlist, optionalPlaylistTrackAndTrack) <- playlists joinLeft (playlistsTracks join tracks on (_.trackId === _.uuid)) on (_.id === _._1.playlistId)
} yield (playlist, optionalPlaylistTrackAndTrack)
注意optionalPlaylistTrackAndTrack
是代表播放列表曲目和曲目的元组的Option。这是因为可能存在没有播放列表轨道的播放列表。
我正在使用 Slick 3 和 Play! 2.4 并且我有一个非常常见的问题,但我无法解决。
我有一个 table playlist
可以在关系 table playlistsTracks
的帮助下链接到某些曲目。我希望能够获得所有播放列表及其曲目关系和曲目。我的问题是,如果他们没有任何关系,我就无法获取播放列表。
这是 3 个 table:
class Playlists(tag: Tag) extends Table[Playlist](tag, "playlists") {
def id = column[Long]("playlistid", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = (id.?, name) <> ((Playlist.apply _).tupled, Playlist.unapply)
}
class PlaylistsTracks(tag: Tag) extends Table[PlaylistTrack](tag, "playliststracks") {
def playlistId = column[Long]("playlistid")
def trackId = column[UUID]("trackid")
def trackRank = column[Double]("trackrank")
def * = (playlistId, trackId, trackRank) <> ((PlaylistTrack.apply _).tupled, PlaylistTrack.unapply)
def aFK = foreignKey("playlistId", playlistId, playlists)(_.id, onDelete = ForeignKeyAction.Cascade)
def bFK = foreignKey("trackId", trackId, tracks)(_.uuid, onDelete = ForeignKeyAction.Cascade)
}
class Tracks(tag: Tag) extends Table[Track](tag, "tracks") {
def uuid = column[UUID]("trackid", O.PrimaryKey)
def title = column[String]("title")
def * = (uuid, title) <> ((Track.apply _).tupled, Track.unapply)
}
目前获取播放列表的代码片段如下所示:
val query = for {
playlist <- playlists
playlistTrack <- playlistsTracks if playlistTrack.playlistId === playlist.id
track <- tracks if playlistTrack.trackId === track.uuid
} yield (playlist, playlistTrack, track)
db.run(query.result) map { println }
它打印出类似 Vector(Playlist, PlaylistTrack, Track)
的内容(我想要的),但我只得到具有关系的播放列表,而不是得到所有播放列表,即使是我想要的没有关系的播放列表。
我尝试了很多方法,例如使用 join(或 joinFull、joinLeft、joinRight...)但都没有成功,不幸的是很难找到一些不仅关系非常简单的示例项目。
您需要在 Playlists 和 PlaylistTracks 之间使用左连接 table 并在 PlaylistTracks 和 Tracks 之间使用 inner join。 该示例中缺少一些内容,因此我实际上无法编译以下内容,但我认为您可以尝试类似的操作:
val query = for {
(playlist, optionalPlaylistTrackAndTrack) <- playlists joinLeft (playlistsTracks join tracks on (_.trackId === _.uuid)) on (_.id === _._1.playlistId)
} yield (playlist, optionalPlaylistTrackAndTrack)
注意optionalPlaylistTrackAndTrack
是代表播放列表曲目和曲目的元组的Option。这是因为可能存在没有播放列表轨道的播放列表。