Slick 3多对多关系:如何获取表的所有元素及其关系(如果存在)?

Sim*_*mon 4 scala slick slick-3.0 playframework-2.4

我正在使用Slick 3和Play!2.4我有一个非常普遍的问题,我无法解决.

我有一个表playlist可以在关系表的帮助下链接到某些轨道playlistsTracks.我希望能够通过他们的曲目关系和他们的曲目获得所有播放列表.我的问题是,如果他们没有任何关系,我就无法获得播放列表.

这是3个表格:

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)
  }
Run Code Online (Sandbox Code Playgroud)

目前,获取播放列表的代码片段如下所示:

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 }
Run Code Online (Sandbox Code Playgroud)

它打印的东西就像Vector(Playlist, PlaylistTrack, Track)(我想要的),但我只是让播放列表有关系,而不是得到所有的播放列表,即使是没有关系的播放列表也是如我所愿.

我尝试过很多东西,比如使用join(或joinFull,joinLeft,joinRight ......)但没有成功,遗憾的是很难找到一些不仅非常简单的关系的示例项目.

小智 7

您需要在播放列表和PlaylistTracks表之间使用左连接,并使用PlaylistTracks和Tracks之间的内部连接.示例中缺少一些内容,因此我无法实际编译以下内容,但我认为您可以尝试以下方法:

val query = for {
  (playlist, optionalPlaylistTrackAndTrack) <- playlists joinLeft (playlistsTracks join tracks on (_.trackId === _.uuid)) on (_.id === _._1.playlistId)
} yield (playlist, optionalPlaylistTrackAndTrack)
Run Code Online (Sandbox Code Playgroud)

注意,它optionalPlaylistTrackAndTrack是表示播放列表轨道和轨道的元组的选项.这是因为可能存在没有播放列表的播放列表.