スクリプトを実行するためのアノテーション @Script

次のDoma 1.7.0で導入しようかなーと検討中です。

使い方は次のようにDaoのメソッドに注釈するだけです。

@Dao(config = ItConfig.class)
public interface ScriptDao {

    @Script
    void create();

    @Script(haltOnError = false)
    void drop();
}

createメソッドに対応するのは、create.scriptというファイルです。create.scriptにはDDLDMLを記述しておきます。こんなかんじで。

CREATE TABLE DEPARTMENT(DEPARTMENT_ID NUMERIC(8) NOT NULL PRIMARY KEY, DEPARTMENT_NO NUMERIC(2) NOT NULL UNIQUE,DEPARTMENT_NAME VARCHAR2(20),LOCATION VARCHAR2(20) DEFAULT 'TOKYO', VERSION NUMERIC(8));
CREATE TABLE ADDRESS(ADDRESS_ID NUMERIC(8) NOT NULL PRIMARY KEY, STREET VARCHAR2(20), VERSION NUMERIC(8));
CREATE TABLE EMPLOYEE(EMPLOYEE_ID NUMERIC(8) NOT NULL PRIMARY KEY, EMPLOYEE_NO NUMERIC(4) NOT NULL ,EMPLOYEE_NAME VARCHAR2(20),MANAGER_ID NUMERIC(8),HIREDATE DATE,SALARY NUMERIC(7,2),DEPARTMENT_ID NUMERIC(8),ADDRESS_ID NUMERIC(8),VERSION NUMERIC(8), CONSTRAINT FK_DEPARTMENT_ID FOREIGN KEY(DEPARTMENT_ID) REFERENCES DEPARTMENT(DEPARTMENT_ID), CONSTRAINT FK_ADDRESS_ID FOREIGN KEY(ADDRESS_ID) REFERENCES ADDRESS(ADDRESS_ID));

INSERT INTO DEPARTMENT VALUES(1,10,'ACCOUNTING','NEW YORK',1);
INSERT INTO DEPARTMENT VALUES(2,20,'RESEARCH','DALLAS',1);

CREATE OR REPLACE PROCEDURE PROC_RESULTSET_OUT
( cur OUT SYS_REFCURSOR, 
  employeeId IN NUMERIC,
  employeeCount OUT NUMERIC
) AS
BEGIN
  OPEN cur FOR SELECT * FROM EMPLOYEE WHERE employee_id > employeeId ORDER BY employee_id;
  SELECT COUNT(*) INTO employeeCount FROM EMPLOYEE;
END PROC_RESULTSET_OUT;
/

Daoのcreateメソッドを実行すると、create.script中のSQLが実行されるというわけです。

この機能の何がうれしいかというと

  • 複数の文を実行できる
  • プロシージャーやトリガーなどのブロック(文の集合)も実行できる
    • RDBMSごとに異なる区切り文字を使用できる(Oracleなら「/」、SQL Serverなら「GO」とDialectで判定します。区切り文字はアノテーションのblockDelimiter要素に明示的に指定も可)
  • create-oracle.script、create-postgres.scriptなどを用意しておけばRDBMSごとに異なるスクリプトを実行できる
  • 実行途中でエラーが発生しても最後まで実行し続けられる(アノテーションのhaltOnError要素をfalseにすればOK)

@Scriptはそんなに頻繁に使うものではないとは思いますが、テストデータの投入など自前のツールを作成するときに威力を発揮します。Doma自身も結合テストhttps://www.seasar.org/svn/doma/trunk/doma-it/)で使っています。ツールとしてはAntにSQLタスクがありますが、使い勝手がいまいちなので自分としてはDomaのこの機能のほうが気に入っています。


SNAPSHOTおいておきます。

追記

@ScriptにマッピングさせるSQLファイルでは、バインド変数コメントや条件コメントは使えません。
いまは、create.sqlみたいに拡張子のsqlをチェックしていますが、@SelectのSQLファイルと区別できるように拡張子はsqlではなくscriptでなければいけない、としようと思います。

追記2 05/03 21:17

上のエントリの内容とSNAPSHOTのリンク先をscriptファイルに対応したものに書き換えました。