ActiveObjectsのCreate文生成機能

JavaのO/RマッパーにActiveObjectsというものがあります。RailsActiveRecordライクな機能をJavaでも使おうという趣旨のライブラリです。Railsのことはよくわかりませんが、JavaのO/Rマッパーにしては、手軽に使えて便利です。インタフェースにgetter、setterを書くだけでテーブルを自動生成してくれますし、CRUD周りの操作もできるようになります。そして、XMLは一切不要です。

とあるアプリケーションのモックで作ってみたのですが、機能をよく把握しないまま使い出しても単純なDB操作だけなら問題ありませんでした。今後も開発の立ち上げ時には重宝しそうです。

ただ、ある程度モックアプリができたところで、込み入ったテーブル操作をする必要がでてきたので、生のSQLが使いたくなってきました。そこでiBATISに乗り換えようとしているのですが、テーブルのCreate文を書くのが面倒なので、ActiveObjectsのテーブル生成機能をリフレクションで無理やり呼ぶコードを書いてみました。

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import net.java.ao.DatabaseProvider;
import net.java.ao.RawEntity;
import net.java.ao.schema.CamelCaseFieldNameConverter;
import net.java.ao.schema.CamelCaseTableNameConverter;
import net.java.ao.schema.FieldNameConverter;
import net.java.ao.schema.SchemaGenerator;
import net.java.ao.schema.TableNameConverter;

import com.grachro.wikilike.model.WikityPage;
import com.grachro.wikilike.model.WikityPageRelation;

public class EntityTool {

    public static void main(String[] args) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        String uri = args[0];
        String username = args[1];
        String password = args[2];

        EntityTool tool = new EntityTool(uri, username, password);
        String[] sqlArray = tool.getCreateSQL(エンティティ1.class, エンティティ2.class,・・・);
        for (String sql : sqlArray) {
            System.out.println(sql);
        }
    }

    private DatabaseProvider provider;

    public EntityTool(String uri, String username, String password) {
        this.provider = DatabaseProvider.getInstance(uri, username, password);
    }

    public String[] getCreateSQL(Class<? extends RawEntity<?>>... entities) throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        TableNameConverter tableNameConverter = new CamelCaseTableNameConverter();
        FieldNameConverter fieldNameConverter = new CamelCaseFieldNameConverter();
        ClassLoader classLoader = SchemaGenerator.class.getClassLoader();

        Method method = findGeneratorMethod();
        method.setAccessible(true);

        return (String[]) method.invoke(null, provider, tableNameConverter, fieldNameConverter, classLoader, entities);

    }

    private Method findGeneratorMethod() throws ClassNotFoundException {
        Class<?> primeClass = Class.forName("net.java.ao.schema.SchemaGenerator");
        Method[] methodArray = primeClass.getDeclaredMethods();
        for (Method m : methodArray) {
            if (m.getName().equals("generateImpl")) {
                return m;
            }
        }
        throw new IllegalStateException("SchemaGenerator#generateImpl is err");
    }
}


※このページのソースコードはパグリックドメインです。
ActiveObjects自体はApache License, Version 2.0で配布されています。