我正在尝试使用slick 3.1.1执行以下SQL查询的等效操作:
SELECT
r.*
FROM Resource r
INNER JOIN User u ON u.id = r.owner_id
INNER JOIN UserCredentials uc ON uc.user_id = u.id
WHERE r.id = <resource id>
我已经表达了这样的查询:
(for ( ((resource,_),_) <- resources
join users on (_.userId === _.id)
join userCredentials on (_._2.id === _.userId))
yield resource).filter(_.id === resourceId).result.headOption
感觉笨拙且难以阅读。是否有更简洁的方式用光滑的方式编写此查询?
答案 0 :(得分:0)
我个人更喜欢方法风格,使用部分函数来显示行名称:
resources.filter(_.id === resourceId).join(users).on {
case (resource, user) => resource.userId === user.id
}.join(userCredentials).on {
case ((_, user), userCredentials) => user.id === userCredentials.userId
}.filter {
case ((resource, _), _) => resource.id === resourceId
}.map {
case ((resource, _), _) => resource
}.result.headOption
你也可以过滤resources
作为你的第一步,这会让事情变得更清洁:
resources.filter(_.id === resourceId).join(users).on {
case (resource, user) => resource.userId === user.id
}.join(userCredentials).on {
case ((_, user), userCredentials) => user.id === userCredentials.userId
}.map {
case ((resource, _), _) => resource
}.result.headOption
我希望有所帮助!
答案 1 :(得分:0)
为了理解救援。内部和交叉连接可以表示为“monadic连接”。以下是使用内部联接:
val query = for {
r <- resources if r.id === resourceId
u <- users if u.id === r.ownerId
uc <- userCredentials if uc.userId === u.id
} yield r
查看slick docs了解更多示例。