7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スタンドアローンGORMをGroovyスクリプトからシュっと利用する

Last updated at Posted at 2017-12-19

G* Advent Calendar 2017 20日目の記事です。

GrailsのO/Rマッピングライブラリである「GORM」は、Grailsから切りはなして単体で使用することもできます。これをスタンドアローンGORMと呼びます。

非WebアプリやGrails以外の他のフレームワークから高機能なORMとして使うことも可能ですし、Grailsでのシステム開発の一部として、バッチやシェルスクリプトやsshでキックしたいとか、シェルアカウントの管理者権限者だけがデータベースにアクセスしたいときには、スタンドアローンGORMが有用なケースがあります。

というのも、そういうケースでは以下のような選択肢があるにはあるのですが、いずれも固有の課題を抱えているからです。

  1. grails scriptsとしてGrailsサービスやGrailsドメインクラスを呼び出す処理などを記述し、Grailsのプロジェクトフォルダ(GRAILS_PROJ/scriptsを含む)に格納して、grailsコマンドで起動。
    問題は、プロジェクトソースコードを運用環境に展開しておく必要があること。
  2. DB処理をWeb APIとして公開して、それを叩くクライアントを開発する。
    転送速度がネックになったり、ポートを公開することでセキュリティの問題になるかもしれない。
  3. Service層をGrailsのRemoting Pluginを使って公開する。
    問題は同上。
  4. SQLを叩く別プログラムを開発する(Groovy SQL, ..)。
    この場合の問題は、GrailsのドメインクラスからDDL生成されたデータベースに対して、生SQLを書くのはかったるいだけではなく、ドメインクラスの制約(constraint)の処理を別途しなければならないということ。

それぞれのケースで示した問題が許容できないとき、スタンドアローンGORMが有用です。

さて、具体的な使用方法としては、Spring Bootのアプリケーションから呼び出すこともできるでしょう。
本記事では、もっとストレートに素のGroovyスクリプトからGORMを呼び出す例を紹介します。

方法

たとえば、こんな感じでGroovyスクリプトを書いて、

@Grab('org.grails:grails-datastore-gorm-hibernate5:6.1.0.RELEASE')
@GrabExclude('javax.transaction:jta')
@Grab('com.h2database:h2:1.4.192')
@Grab('org.apache.tomcat:tomcat-jdbc:8.5.0')
@Grab('org.slf4j:slf4j-log4j12')
import java.lang.String
import org.grails.orm.hibernate.HibernateDatastore
import grails.gorm.annotation.Entity

@Entity
class Book {
    String title
    static hasMany = [authors: Author]
    String toString() {"$id: $title"}
}

@Entity
class Author {
    String name
    static hasMany = [books: Book]
    static belongsTo = Book
    String toString() {"$id: $name"}
}

def hibernateDatastore = new HibernateDatastore([
        'hibernate.hbm2ddl.auto': 'create-drop',
        'dataSource.driverClassName': 'org.h2.Driver',
        'dataSource.url': 'jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE',
        'dataSource.username': 'sa',
        'dataSource.password': '',
    ],
    Author)

Author.withTransaction {
    Author a = new Author(name:'上原 潤二');
    Book b1 = new Book(title: 'プログラミングGROOVY').addToAuthors(a).save()
    Book b2 = new Book(title: 'Grails徹底入門').addToAuthors(a).save()
    println Book.findByTitleLike('G%')
}

GroovyおよびJDKがインストールされていれば、以下で実行できます。

> groovy groovyスクリプトファイル名

GroovyやJDK以外の何かを事前ダウンロードしたりインストールしたりフォルダ構成を考えたりコンパイルしたりビルドしたりビルドスクリプトを書いたりデプロイしたりパッケージングしたりが一切不要なのが利点です✌。

なお、上記では@Entityでドメインクラスを定義していますが、データベースがGrailsアプリケーションの一部であるなら、Grailsアプリケーション本体のwar(やjar)に含まれるドメインクラスのクラスファイルのjarをクラスパスに含めれば別に書かなくても利用可能です(多分)。

7
3
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
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?