LoginSignup
2
2

More than 5 years have passed since last update.

[Grails]whereクエリの使い方サンプル

Posted at

サンプルソース

ドメイン

Person.groovy
package sqltest

class Person {

    String name
    Integer age
    Editor editor
    static hasMany = [hobbies:Hobby]

    static constraints = {
    }
    static mapping = {
        version: false
    }

    static adults = where {
        age >= 20
    }

    def sayHello() {
        "Hello! I am ${name}"
    }

    String toString() {
        "${name}(${age})"
    }
}
Hoggy.groovy
package sqltest

class Hobby {

    String name
    static constraints = {
    }
    static mapping = {
        version: false
    }
}

Editor.groovy
package sqltest

class Editor {

    String name

    static constraints = {
    }
    static mapping = {
        version:false
    }
}

テストデータ登録

BootStrap.groovy
import sqltest.Editor
import sqltest.Hobby
import sqltest.Person

class BootStrap {

    def init = { servletContext ->
        environments {
            development {
                def h1 = new Hobby(name:"Hobby-1").save(flush:true)
                def h2 = new Hobby(name:"Hobby-2").save(flush:true)
                def h3 = new Hobby(name:"Hobby-3").save(flush:true)

                def e1 = new Editor(name:"vim").save(flush:true)
                def e2 = new Editor(name:"emacs").save(flush:true)

                def p1 = new Person(name:"koji-1", age: 19, editor: e1).addToHobbies(h1).save(flush:true)
                def p2 = new Person(name:"koji-2", age: 20, editor: e2).addToHobbies(h2).save(flush:true)
                def p3 = new Person(name:"koji-3", age: 99, editor: e1).addToHobbies(h1).addToHobbies(h2).addToHobbies(h3).save(flush:true)
                def p4 = new Person(name:"koji-1", age: 20, editor: e2).addToHobbies(h2).save(flush:true)

                p1.addToHobbies(h3).save(flush:true)
                p2.addToHobbies(h3).save(flush:true)

                p1.removeFromHobbies(h3)
            }

            test {

            }
            production {

            }
        }
    }
    def destroy = {
    }

}

使い方

HelloController
package sqltest

import grails.gorm.DetachedCriteria

class HelloController {

    def where () {
        DetachedCriteria a = Person.where {
            name == "koji-2"
        }

        Person p = a.find()
        render p.sayHello()
    }

    // ドキュメントにはわかりやすく書かれていないけど、Groovyの正規表現っぽい構文で==~と=~
    // が使えるけど、利用できるのは結局SQLのlike構文なので、正規表現が使えるわけではない。
    def where2() {
        DetachedCriteria query = Person.where {
            name ==~ /koji-%/
        }
        render query.list().size()
    }

    // 少し複雑な条件になると、Groovyライクな条件指定ができるwhereクエリのほうが
    // ダイナミックファインダーよりスマートかも?
    def where3() {
        DetachedCriteria query = Person.where {
            (name == "koji-1" && age == 20) || age == 99
        }
        render query.list()
    }

    // whereクエリは遅延評価なので、ドメインの中に事前に用意しておくことも可能。
    // 結果的に名前をつけることになるので、どういったデータが抽出されるのかわかりやすくなる。
    def where4() {
        render Person.adults.list()
    }

    // 関連を持っているドメインも検索できる。
    def where5() {
        Editor e = Editor.findByName("vim")
        DetachedCriteria query = Person.where {
            editor.name == e.name
            // こっちもOK
            //editor.name == Editor.findByName("vim").name
        }
        render query.list()
    }

    // ただし1対多だとsizeしか使えない。。。
    // 1対多の扱いはダイナミックファインダーでも微妙に挙動が理解しづらい。
    def where6() {
        DetachedCriteria query = Person.where {
            hobbies.size() >= 2
        }
        render query.list()
    }

    // まず20歳のユーザの一覧を取得する。そのユーザたちの名前と一致するユーザを抜き出してくる。
    // なので、当然未成年者が含まれる可能性がある。
    def where7() {
        DetachedCriteria query = Person.where {
            name in where {age == 20}.name
        }
        render query.list()
    }

    // 成人ユーザの一覧を取得し、、その中から最も若い年齢を取得する。
    // その年齢と一致するユーザの一覧を取得する。
    // つまり、成人ユーザで最も若いユーザの一覧が取得される。
    def where8() {
        DetachedCriteria query = Person.where {
            age == where { age > 19 }.min('age')
        }
        render query.list()
    }
}

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2