About

ドキュメント

Javadoc

モジュール

プロジェクト文書

Built by Maven

説明

概要

SQLファイルに対するテストクラスを作成します。 ここでのSQLファイルとは、JdbcManagerのSQLファイルによる操作 で使用されるSQLファイルを指します。

例えば、次のようなコードを生成できます。

/**
 * SQLファイルのテストクラスです。
 * <p>
 * このファイルは修正されることを意図していません。
 * SQLファイルのテストを独自に行いたい場合は、サービスやエンティティのテストクラスを使用してください。
 * </p>
 *
 * @author S2JDBC-Gen
 */
public class SqlFileTest extends S2TestCase {

    private JdbcManager jdbcManager;

    /**
     * 事前処理をします。
     * 
     * @throws Exception
     */
    @Override
    protected void setUp() throws Exception {
        super.setUp();
        include("s2jdbc.dicon");
    }

    /**
     * SQLファイルをテストします。
     * 
     * @throws Exception
     */
    public void testSqlFile0Tx() throws Exception {
        String path = "META-INF/sql/Address/getStreet.sql";
        new SqlFile(path).execute();
    }

    /**
     * SQLファイルをテストします。
     * 
     * @throws Exception
     */
    public void testSqlFile1Tx() throws Exception {
        String path = "META-INF/sql/Employee/updateEmployeeName.sql";
        new SqlFile(path).execute();
    }

    /**
     * SQLファイルを表すクラスです。
     * 
     * @author S2JDBC-Gen
     */
    public class SqlFile {

        /** SQL */
        protected String sql;

        /** 内部的なJDBCマネジャ */
        protected JdbcManagerImplementor implementor;

        /**
         * インスタンスを構築します。
         * 
         * @param path
         *            SQLファイルのパス
         */
        public SqlFile(String path) {
            implementor = JdbcManagerImplementor.class.cast(jdbcManager);
            this.sql = getSql(path);
        }

        /**
         * SQLを返します。
         * 
         * @param path
         *            SQLファイルのパス
         * @return SQL
         */
        protected String getSql(String path) {
            if (path.endsWith(".sql")) {
                path = path.substring(0, path.length() - 4);
            }
            String dbmsName = implementor.getDialect().getName();
            if (dbmsName != null) {
                String sql = readSql(path + "_" + dbmsName);
                if (sql != null) {
                    return sql;
                }
            }
            String sql = readSql(path);
            if (sql != null) {
                return sql;
            }
            throw new ResourceNotFoundRuntimeException(path);
        }

        /**
         * SQLをファイルから読み取ります。
         * 
         * @param path
         *            SQLファイルのパス
         * @return SQL
         */
        protected String readSql(String path) {
            InputStream is = ResourceUtil.getResourceAsStreamNoException(path,
                    "sql");
            if (is == null) {
                return null;
            }
            Reader reader = InputStreamReaderUtil.create(is, "UTF-8");
            String sql = ReaderUtil.readText(reader);
            if (sql.length() > 0 && sql.charAt(0) == '\uFEFF') {
                sql = sql.substring(1);
            }
            sql = sql.trim();
            if (sql.endsWith(";")) {
                sql = sql.substring(0, sql.length() - 1);
            }
            return sql;
        }

        /**
         * SQLを実行します。
         */
        public void execute() {
            System.out.println(sql);
            Connection connection = org.seasar.extension.jdbc.util.DataSourceUtil
                    .getConnection(implementor.getDataSource());
            try {
                PreparedStatement ps = ConnectionUtil.prepareStatement(
                        connection, sql);
                try {
                    PreparedStatementUtil.execute(ps);
                } finally {
                    StatementUtil.close(ps);
                }
            } finally {
                ConnectionUtil.close(connection);
            }
        }
    }
}

テストクラスでは、実際にSQLを発行し次のことを確認します。

  • SQLが構文的に間違っていないこと
  • SQLで存在しないテーブルやカラムを参照していないこと

このとき、実行されるSQLはSQLファイルに記述されたままの文で実行されます。 JdbcManagerのAPIを使ったときのようにバインド変数コメントが解決されるわけではないことに注意してください。 テストメソッドは、testSqlFile連番 Txという名前でSQLファイルごとに生成されます。

SQLファイルに対するテストを実行することで、IDEのリファクタリング機能では検出できないSQL文上の修正対象を検出したり、修正漏れを防いだりすることができます。

テストクラスは、常に自動生成するようにしてください。

パラメータ

Antタスクへのパラメータを以下に示します。

トップレベルのパラメータ

属性 説明 デフォルト値 必須
classpathDir エンティティクラスを含むクラスパスのディレクトリです。このディレクトリはタスクの実行時のクラスパスに含まれている必要があります。 - YES
rootPackageName ルートパッケージ名です。 "" NO
subPackageName テストクラスのサブパッケージ名です。テストクラスは、rootPackageNameとこの値をピリオドで連結したパッケージに配置されているとみなされます。この値が空文字の場合は、テストクラスは、rootPackageNameで表されるパッケージに配置されているとみなされます。 "" NO
shortClassName テストクラスの単純名です。 "SqlFileTest" NO
useS2junit4 "true"の場合、S2JUnit4 を使ったテストコードを生成します。"false"の場合、S2Unit を使ったテストコードを生成します。 "false" NO
templateFileName テストクラスのテンプレートファイル名です。 "java/sqlfiletest.ftl" NO
templateFileEncoding テンプレートファイルのエンコーディングです。 "UTF-8" NO
templateFilePrimaryDir テンプレートファイルを検索する際の優先ディレクトリです。 - NO
javaFileDestDir Javaファイルの出力先ディレクトリです。 "src/test/java" NO
javaFileEncoding Javaファイルのエンコーディングです。 "UTF-8" NO
overwrite "true"の場合、テストクラスのJavaファイルを上書きします。 "true" NO
configPath JdbcManagerのコンポーネント定義を含む設定ファイルです。このタスクの実行に使用されます。また、テストコードではこの設定ファイルがincludeされます。 "s2jdbc.dicon" NO
env 環境名です。 "ut" NO
jdbcManagerName JdbcManagerのコンポーネント名です。接続先のデータベースはJdbcManagerのコンポーネント名によって決まります。 "jdbcManager" NO
factoryClassName S2JDBC-Genの公開されたインタフェースの実装を作成するファクトリのクラス名です。S2JDBC-Genをカスタマイズする場合に独自のファクトリクラスを指定できます。ここに指定するクラスはorg.seasar.extension.jdbc.gen.internal.factory.Factoryインタフェースを実装している必要があります。 "org.seasar.extension.jdbc.gen
.internal.factory.FactoryImpl"
NO
commandInvokerClassName S2JDBC-Genのコマンドを呼び出すクラスの名前です。コマンドの呼び出し前後で任意の処理を実行したい場合に指定します。ここに指定するクラスはorg.seasar.extension.jdbc.gen.command.CommandInvokerインタフェースを実装している必要があります。 "org.seasar.extension.jdbc.gen
.internal.command.CommandInvokerImpl"
NO
classpath このタスクを実行する際のクラスパスです。 - classpathrefが指定されていない場合YES
classpathref このタスクを実行する際のクラスパスの参照です。 - classpathが指定されていない場合YES

ネストした要素として指定されるパラメータ

SqlFileSet

SQLファイルを指定するためには、<SqlFileSet>要素を使用します。 <SqlFileSet>はAntの<FileSet>と同じです。 使用可能な属性やネストした要素についてはAntのドキュメントを参照してください。

jvmArg

このタスクの大部分の処理は別VMで行われます。VMに引数を渡す場合は<jvmarg>要素を使用します。 これはAntのJavaタスクで使用できる<jvmarg>と同じです。 使用可能な属性やネストした要素についてはAntのドキュメントを参照してください。

SQLファイルを指定する

SQLファイルを指定するには、<SqlFileSet>を使用します。 SQLファイルはclasspathDir属性に指定されるディレクトリ以下に存在している必要があります。

<gen-sqlfiletest
    classpathDir="build/classes"
    rootpackagename="examples"
    classpathref="classpath">
    <sqlfileset dir="build/classes">
        <include name="META-INF/sql/**/*.sql" />
    </sqlfileset>
</gen-sqlfiletest>

上記の定義を利用すると、META-INF/sqlディレクトリ以下の「.sql」という拡張子を持つファイルがテストの対象になります。

独自のテンプレートファイルを使用する

任意のディレクトリに独自のテンプレートファイルを置き、templateFilePrimaryDir属性にそのディレクトリを指定することで、 独自のテンプレートファイルを使用できます。

S2JDBC-Genのテンプレートは、配布ファイルのresources/tempaltesディレクトリ以下にあります。 SQLファイルのテストクラスのテンプレートはjava/sqlfiletest.ftlになります。 これをコピーして、修正を加えるのが良いでしょう。 テンプレートの記述方法についてはFreeMarker のドキュメントを参照してください。

テンプレートファイルを格納するディレクトリをmytempletesとする場合、 修正した独自テンプレートを使用するにはテンプレートをmytempletes/java/sqlfiletest.ftlと配置し、templateFilePrimaryDir属性にmytempletesを指定します。

<gen-sqlfiletest
    classpathDir="build/classes"
    rootPackageName="examples"
    templateFilePrimaryDir="mytempletes"
    classpathRef="classpath">
    <sqlfileset dir="build/classes">
        <include name="META-INF/sql/**/*.sql" />
    </sqlfileset>
</gen-sqlfiletest>

mytempletes/my-sqlfiletest.ftlのように、テンプレートファイルを任意の名前で配置したい場合は、 templateFilePrimaryDir属性に加え、templateFileName属性も指定します。

<gen-sqlfiletest
    classpathDir="build/classes"
    rootPackageName="examples"
    templateFilePrimaryDir="mytempletes"
    templateFileName="my-sqlfiletest.ftl"
    classpathRef="classpath">
    <sqlfileset dir="build/classes">
        <include name="META-INF/sql/**/*.sql" />
    </sqlfileset>
</gen-sqlfiletest>

生成するJavaファイルに共通のヘッダーとしてコピーライトを含める

lib.ftlというファイルを作成し、これをtemplateFilePrimaryDir属性に指定するディレクトリに配置します。 lib.ftlには次のようにcopyrightの定義をします。

<#assign copyright>
/*
 * Copyright 2008-2009 ...
 * All rights reserved.
 */
</#assign>
mytempletes/lib.ftlと配置する場合、タスクの定義は次のようになります。

<gen-sqlfiletest
    classpathDir="build/classes"
    rootPackageName="examples"
    templateFilePrimaryDir="mytempletes"
    classpathRef="classpath">
    <sqlfileset dir="build/classes">
        <include name="META-INF/sql/**/*.sql" />
    </sqlfileset>
</gen-sqlfiletest>

copyright.ftlにコピーライトを記述することもできます(過去バージョンとの互換機能として残されています)。 copyright.ftlを使う場合は、#assignタグを使わずコピーライトのみを指定してください。 lib.ftlと同様、copyright.ftlはtemplateFilePrimaryDir属性に指定するディレクトリに配置する必要があります。

生成するJavaファイルにauthorを指定する

lib.ftlというファイルを作成し、これをtemplateFilePrimaryDir属性に指定するディレクトリに配置します。 lib.ftlには次のようにauthorの定義をします。

<#assign author="Nakamura">
mytempletes/lib.ftlと配置する場合、タスクの定義は次のようになります。

<gen-sqlfiletest
    classpathDir="build/classes"
    rootPackageName="examples"
    templateFilePrimaryDir="mytempletes"
    classpathRef="classpath">
    <sqlfileset dir="build/classes">
        <include name="META-INF/sql/**/*.sql" />
    </sqlfileset>
</gen-sqlfiletest>