LoginSignup
2
1

More than 5 years have passed since last update.

[Grails]GORMでlike

Posted at

以下のようなドメインを用意。

package gormtest

class Person {

    String name
    Integer age

    static constraints = {
    }
}

Bootstrapに以下のサンプルレコードを記述してrun-app

import gormtest.Person
import grails.util.Environment

class BootStrap {

    def init = { servletContext ->
        Environment.executeForCurrentEnvironment {
            development {
                new Person(name:"Tarou-A", age:20).save(flush:true)
                new Person(name:"Tarou-B", age:21).save(flush:true)
                new Person(name:"C-Tarou", age:22).save(flush:true)
                new Person(name:"D-Tarou", age:23).save(flush:true)
                new Person(name:"E-Tarou-E", age:24).save(flush:true)
                new Person(name:"E-Tarou-E", age:25).save(flush:true)
            }
            test {}
            production {}
        }
    }
    def destroy = {
    }
}

コントローラとして以下の物を用意して確認する。

package gormtest

class LikeController {

    // 基本形(ダイナミックファインダー)
    def index() {
        // SQLのlike構文と同等
        // なので、一文字だけチェックしたい場合は「_」を使う
        def prefix = Person.findAllByNameLike(/Tarou%/) // 前方一致
        def prefix2 = Person.findAllByNameLike(/Tarou_A/) // 前方一致
        def partial = Person.findAllByNameLike(/%Tarou%/) // 部分一致
        def end = Person.findAllByNameLike(/%Tarou/)// 後方一致

        println prefix  // [gormtest.Person : 1, gormtest.Person : 2]

        render """
            <h1>ダイナミックファインダー</h1>
            <h2>前方一致</h2>
            ${prefix.collect{it.name}.join("<br />")}<br />

            <h2>前方一致(一文字チェック)</h2>
            ${prefix2.collect{it.name}.join("<br />")}<br />

            <h2>部分一致</h2>
            ${partial.collect{it.name}.join("<br />")}<br />

            <h2>後方一致</h2>
            ${end.collect{it.name}.join("<br />")}<br />
        """
    }

    // whereクエリー(Grails2.0から利用可能)
    // Detached Criteriaの拡張版
    // Detached Creiteriaについてはここを参照
    // http://grails.jp/doc/latest/guide/single.html#detachedCriteria
    def index2() {
        def prefix = Person.where {name ==~ /Tarou%/} // 前方一致
        def prefix2 = Person.where {name ==~ /Tarou_A/} // 前方一致
        def partial = Person.where {name ==~ /%Tarou%/} // 部分一致
        def end = Person.where {name ==~ /%Tarou/} // 後方一致

        // whereクエリは、DetachedCriteriaのインスタンスが帰ってきている。
        // この時点ではまだ実行されていない。
        // DetachedCriteriaに用意されている、list()やget()と言ったメソッドを実行した時点で初めてDBへの問い合わせが実行される。
        println prefix  // grails.gorm.DetachedCriteria@34b5cf3b

        render """
            <h1>whereクエリー</h1>
            <h2>前方一致</h2>
            ${prefix.list().collect{it.name}.join("<br />")}<br />

            <h2>前方一致(一文字チェック)</h2>
            ${prefix2.list().collect{it.name}.join("<br />")}<br />

            <h2>部分一致</h2>
            ${partial.list().collect{it.name}.join("<br />")}<br />

            <h2>後方一致</h2>
            ${end.list().collect{it.name}.join("<br />")}<br />
        """
    }

    // その他
    def index3() {
        // whereクエリを使う代わりに、findメソッドとfindAllメソッドに条件を渡す事も出来る。
        // 渡せる条件の形式などはwhereクエリーと同じだが、即座に実行される。
        def partial = Person.findAll{ name ==~ /%Tarou%/ }

        // ある程度複雑なクエリを生成したい場合は以下のような形でも実現出来る
        // Tarouという文字列を含むレコードかつ、年齢が偶数のPersonオブジェクトを取得してみる。
        // なお、剰余を求めるx%2==0のような構文は使えないみたい。
        def partial2 = Person.where{
            name ==~ /%Tarou%/ && age in [20,22,24]
        }

        render """
            ${partial2.collect{it.name + ":" + it.age}.join("<br />")}
        """
    }
}

今回コードには書いてないけど、 =~Ilike() を使うと、大文字小文字が無視出来る。

備考

今回の内容だと、純粋にlike検索と言うには、ちょっとGORMの使い方の説明が入り込んでしまっている感あり。
いつかGORM、DB周りのことも調べてまとめて別途記事にしたい。

2
1
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
1