ドメインクラスGORM

永続化するためのモデルをGrailsではドメインクラスと呼ぶ。ドメインクラスには、必要なプロパティと制約、ORマッピングの定義をするマッピングDSL等を記述する。記述した定義をもとに、Hibernateの定義、テーブルの生成等を自動で行ってくれる。

データ参照には、ダイナミックファインダ、クライテリアビルダ等、Groovy DSLを活用した仕組みで操作できる。もちろんHibernateをベースに実装されているので、HQL(Hibernateクエリ言語)も利用できる。

ドメインクラスと、参照の仕組みのを、GORM ( ゴーム Grails O/R マッピング)という。本稿では、生成・参照の一部を紹介する。なお、詳細は公式リファレンスを参照して頂きたい。

ドメインクラス生成コマンド

% grails create-controller com.example.Book (パッケージ名から生成したいドメイン名称を指定)

Book.groovy

package com.example

class Book {
  //マッピングDSL:テーブル名、データ型の指定等が行える。
  static mapping = {
    id generator:'sequence', params:[sequence:'book_id_seq']
    columns {
      comment sqlType:'varchar(4000)'
    }
  }
  //プロパティ:テーブルのフィールド名としても使用される。
  //いちばんシンプルなドメインクラスは、この部分のみ記述するばよい。
  String title
      String author
  String comment

  //制約:バリデーション、ビューでの自動生成されるフォーム用情報にも使われる。
  static constraints = {
    title nullable:false,blank:false
    author nullable:false,blank:false
    comment nullable:false,blank:false,maxSize:4000
  }
}

GORM / データ操作

データ操作用の機能などは、動的に追加されたメソッドを使用する。実装方法については、以下のサンプルコードを参照して頂きたい。

def book = new Book()
book.title = 'Grails徹底入門'
// .... 省略 ....
//保存を行う
book.save() 
// データの取得
    book.get(1) // idを指定して取得
book.getAll(7,5,8) //複数idを指定して取得
book.list() // 全リスト

//データの削除
def book = Book.get(1)
book.delete()

GORM / ダイナミックファインダ

ダイナミックファインダとは、メソッドをキャメルケースで検索したいフィールド名や、その条件を指定してクエリが記述できる仕組みだ。内部的にメソッド名を変換して、動的にクエリが解釈され実行される。

説明用の例として、以下のドメインクラスを使用する。

class Book {
    String title
    Date releaseDate
    Author author
}

ドメインクラスBookに対しての、ダイナミックファインダの記述。

def book = Book.findByTitle("Grails 徹底入門")
def books = Book.findAllByTitleLike("Groovy%")
book = Book.findByReleaseDateBetween( firstDate, secondDate )
book = Book.findByReleaseDateGreaterThan( someDate )
book = Book.findByTitleLikeOrReleaseDateLessThan( "%Something%", someDate )
c = Book.countByReleaseDateBetween(firstDate, new Date())
def results = Book.listOrderByTitle(max:10)

ご覧の通り、ダイナミックファインダは、findBy、findAllBy、listOrderBy、countByで始まり、フィールド名と条件などをつなげて記述する。詳細は公式ドキュメントを参照してほしい。

GORM / クライテリアビルダ

クエリをDSLで記述する、もう一つのGrailsでのクエリ発行方法がクライテリアビルダだ。この内容も詳しくは公式ドキュメントを参照してほしい。

def c = Account.createCriteria()
def results = c {
    between("balance", 500, 1000)
    eq("branch", "London")
    or {
        like("holderFirstName", "Fred%")
        like("holderFirstName", "Barney%")
    }
    maxResults(10)
    order("holderLastName", "desc")
}