3
3

More than 5 years have passed since last update.

[Grails]Serviceの中で任意のdataSourceを使って生のSQLを実行する方法

Posted at

概要

下書きが溜まってしまったのでとりあえず投稿。そのうち文章とか修正予定。

GrailsはDataSource.groovyの中の各環境(dev, test, prod)にそれぞれ定義されたdataSourceの定義に従ってデータベースに接続してくれます。
普段はそれでいいのですが、ある特定のデータを取得するときだけは別のデータベースに繋ぎたい場合はどうすればいいのでしょうか?
通常は自分自身が利用するデータベースは一つだけですが、やはり要件によっては別のシステムのデータベースにアクセスしてデータを取得しなければならない、という状態は当然想定されます。

今回、独自のdataSourceを定義して、それをServiceの中から利用する方法を調べたのでメモします。

オリジナルのdataSourceの定義方法

オリジナルのdataSourceの定義自体はすごく簡単で、対象の環境(dev, test, prod)の中で、
dataSource_オリジナルの任意の名前
という書式で定義します。
dataSource_は固定です。
例えば以下のような感じ。

grails-app/conf/DataSource.groovy
development {
    dataSource {
        dbCreate = "create-drop"
        url = "jdbc:postgresql://localhost:5432/postgesqldb"
    }
    dataSource_mysql {
        dialect = org.hibernate.dialect.MySQLInnoDBDialect
        driverClassName = 'com.mysql.jdbc.Driver'
        username = 'mysqluser'
        password = '******'
        url = 'jdbc:mysql://localhost/mysqldb'
    }
}

JDBCドライバどうすんの?って話ですが、それはGrailsのBuildConfig.groovyのdependenciesに定義してしまえばOKです。非常にシンプル!

独自のdataSourceをServiceの中で使う

ここが落とし穴で、公式ドキュメントなどには、Serviceクラスの中で、以下の様に宣言するようにと説明されていますが、単純にServiceからgroovy.sql.Sqlを使いたい場合はコレではダメです。

ダメなバージョン
class DataService {

    // 独自dataSourceのアンダーバー以降を指定する
    static datasource = 'mysql'

    def serviceMethod() {

        // groovy.sql.Sqlのコンストラクタにはこの場合'mysql'というStringが渡されることになる。
        // でもStringを取るgroovy.sql.Sqlのコンストラクタは無いので当然例外。
        def sql = new Sql(dataSource)
        def query = """
            SELECT COUNT(*) FROM hoge
        """
        println sql.rows(query)
    }

以下のようにする必要が有ります。

成功するバージョン
class DataService {

    Sql sql
    // 独自dataSource用のセッターを宣言する。
    // 独自dataSource名の先頭にsetをつけて、先頭文字を大文字にするだけ。
    void setDataSource_mysql(dataSource) {
        sql = new Sql(dataSource)
    }

    def serviceMethod() {

        def query = """
            SELECT COUNT(*) FROM hoge
        """
        println sql.rows(query)
    }

GORMからも同じように別のデータベースにアクセスできるようですが、それはまた別の機会に調べたいと思います。

参考

5 Configuration 2.4.4
Grails User (Old Archive) - Using multiple datasources
[Grails]servicesで直接SQLを実行する方法
Sql (Groovy 2.2.1)

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