2013-04-28 3 views
0

관련 개체가 두 개인 도메인에서 쿼리해야합니다.두 개의 연관에 대한 Grails GORM 쿼리

class UserVideo { 
    User user 
    Video video 
} 
class User { 
    String name 
} 
class Video { 
    String title 
} 

주어진 사용자에게 속한 UserVideos와 video.title이 문자열과 같은 모든 UserVideos를 찾아야합니다. 예를 들어 "사용자 'Fred'에 속한 모든 UserVideos를 찾고 Video.title은 '% Potter %'와 같습니다." 아무리 노력해도 아무 것도 작동하지 않습니다. 여기

def list(Integer max, String title) { 
    def userName = springSecurityService?.principal?.username 
    def user = User.findByUsername(userName) 
    params.max = Math.min(max ?: 10, 100) 
    def results 
    if (title) { 
     def c = UserVideo.createCriteria() 
     results = c.list { 
      eq("user", user) 
      video { 
       ilike("title", "%${title}%") 
      } 
     } 
    } else { 
     results = UserVideo.findAllByUser(user, params) 
    } 
    def userVideos = results.collect({ UserVideo uv -> 
     [uId: uv.user?.id, vId: uv.video?.id, number: uv.number, title: uv.video?.title, 
       format: uv.video?.format?.name, rating: uv.video?.rating?.name, genres: uv.video?.genreNames] 
    }) 
    [userVideos: userVideos, total: UserVideo.count()] 
} 

내가 오류입니다 :

URI 
/movies/userVideo/list 
Class 
org.h2.jdbc.JdbcSQLException 
Message 
Column "VIDEO_ALIA1_.TITLE" not found; SQL statement: select this_.user_id as user1_2_0_, this_.video_id as video2_2_0_, this_.number as number2_0_ from user_video this_ where this_.user_id=? and (lower(video_alia1_.title) like ?) [42122-170] 

답변

1

당신은 도메인 클래스에 executeQuery을 사용할 수 있습니다 요청으로

, 여기에 내가 내 행동을 가지고있는 코드입니다.

샘플이

def c = UserVideo.createCriteria() 
def results = c.list { 
    eq("user", User.findByName("Fred")) 
    video { 
    ilike("title", "%Potter%") 
    } 
} 

업데이트와 같은

def newUser = new User(name: "Fred") 
def video = new Video(title: "Harry Potter") 
[newUser, video]*.save(flush: true) 

def userVideo = new UserVideo(user: newUser, video: video) 
userVideo.save(flush: true) 

def result = UserVideo.executeQuery(
        "Select distinct uv from UserVideo uv " + 
        "where uv.user.name = :userName " + 
        "and uv.video.title like :title", 
        [userName : "Fred", title: "%Potter%"], 
        [max: 10, offset: 10]) //EDIT 
//Pagination included. (max: 10, offset: 10) can also be part of the params maps like 
//[userName : "Fred", title: "%Potter%", max: 10, offset: 10] 

assert "Fred has the movie Harry Potter" == 
      "${result[0].user.name} has the movie ${result[0].video.title}" 
+0

감사를 사용해보십시오. 그러나 페이징 정보도 전달해야합니다 (즉, offset = 10? max = 10). "findAllBy"호출을 할 때, 단순히 params 해시를 전달하기 만하면됩니다. 예 : UserVideo.findAllByUser (user, params). executeQuery와 비슷한 호출이 있습니까? – wholladay

+0

예,'executeQuery'에도 페이지 매김 매개 변수를 전달할 수 있습니다. 내 편집을 참조하십시오. – dmahapatro

+0

우수, 정말 고마워! 이제 보너스 질문을 위해 ... 페이징을하고 있기 때문에 어떻게 전체 일치 항목이 무엇인지 판단 할 수 있습니까? 예를 들어 "% to %"를 내 제목 값으로 사용하면 제목에 "to"가 포함 된 200 개의 일치 항목이 있음을 알아야합니다. 그러나 최대 10자를 넘기 때문에 10 개의 결과 만 얻습니다. 나는 두 개의 분리 된 호출을 할 수있다. (하나는 최대 값이고 다른 하나는 호출하지 않는다.)하지만 이것은 대단히 비효율적이다. – wholladay

2

뭔가 -이 솔루션이 작동하는 것 같다, HQL에게

UserVideo.executeQuery(""" 
    Select uv 
    From UserVideo as uv join uv.video v join uv.user u 
    where lower(v.title) like lower(:title) 
    and u = :user 
""", [user: user, title: "%${title}%"]) 
+0

내 SQL이 있다면 rlike 함수도 사용할 수 있습니다. 그 방법으로 어디에서든지, 시작, 중간 또는 끝까지 일치시킬 수 있습니다. –

+0

전체 액션 코드 게시 –

+0

시도 할 때 다음 오류가 발생합니다. URI /movies/userVideo/list 클래스 org.h2.jdbc.JdbcSQLException 메시지 "VIDEO_ALIA1_.TITLE"열을 찾을 수 없습니다. SQL 문 : this_.user_id를 user1_2_0_, this_.video_id를 video2_2_0_, this_.number를 number2_0_으로 user_video this_에서 선택하십시오. this_.user_id =? and (lower (video_alia1_.title) like?) [42122-170] – wholladay