2013-04-28 47 views
0

我需要在具有兩個關聯對象的域上進行查詢。關於兩個關聯的Grails GORM查詢

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

我需要找到屬於給定用戶,並在video.title就像是一個字符串的所有UserVideos。例如「查找屬於用戶'Fred'的所有用戶視頻,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 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」調用時,我只需傳入參數散列,它做的是正確的事情。例如:UserVideo.findAllByUser(用戶,參數)。是否有與executeQuery類似的調用? – wholladay 2013-04-29 14:37:29

+0

是的,你也可以在'executeQuery'中傳遞分頁參數。看我的編輯。 – dmahapatro 2013-04-29 15:52:36

+0

非常好,非常感謝!現在有獎金問題...由於我在做分頁,我怎麼能確定總的匹配是什麼?例如,如果我使用「%to%」作爲標題值,我需要知道標題中包含「to」的200個匹配項。但是,由於我最多輸了10個,所以我只能得到10個結果。我可以做兩個不同的調用(一個調用max,另一個不調用),但這看起來非常低效。 – wholladay 2013-04-29 17:01:04

2

像這樣的事情

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

更新 - 嘗試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函數。這樣,你可以在任何地方匹配tithle,開始,中間或結尾 – 2013-04-28 09:08:24

+0

後整個操作代碼 – 2013-04-29 11:20:14

+0

當我嘗試,我得到了以下錯誤:URI /電影/ userVideo /列表 類 org.h2.jdbc.JdbcSQLException 消息 未找到列「VIDEO_ALIA1_.TITLE」; SQL語句:選擇this_.user_id爲user1_2_0_,this_.video_id爲video2_2_0_,this_.number爲number2_0_ from user_video this_ where this_.user_id =?和(更低(video_alia1_.title)喜歡?)[42122-170] – wholladay 2013-04-29 14:17:16