2016-10-28 3 views
0

나는 다음과 같은 SQL 쿼리에 해당을 실행하기 위해 매끄러운 3.1.1를 사용하는 것을 시도하고는 :이 쿼리를 매끄럽게 표현하는 것이 더 읽기 쉽고 관용적 인 방법이 있습니까?

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 

그것은 unwieldly 하드 느낌 읽다. 매끄러운이 쿼리를 작성하는 더 깨끗한 방법이 있습니까?

답변

0

구조에 대한 이해. 내부 조인과 교차 조인은 "모나드 조인"으로 표현할 수 있습니다. 다음은 내부 조인 사용 :

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.

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 

을 도움이 되었길 바래요!