S2JDBC-GEN+Mavenの環境をセットアップする方法
先週末から悩んでいたDBのマイグレーションの問題にS2JDBC-GENで対応することにした。本当はエンティティクラスとかを自動生成してくるからアプリでもそれを使えればいいんだけど、今回は間に合わないので、S2JDBC-GENは、DBのマイグレーションツールとして使うことにした。
で、ようやくセットアップ出来たのでメモしておく。ちょい微妙なところもあるけど、とりあえずこれでいけるかな。
まず、Maven用のプロジェクトをつくり、Eclipseでも開けるようにする。(Maven2はセットアップ済み)
> mvn archetype:create -DgroupId=com.example -DartifactId=DbProject > cd DbProject > mvn eclipse:eclipse
そして、そのディレクトリにできたpom.xmlを以下のように編集。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>DbProject</artifactId> <packaging>jar</packaging> <version>1.0-SNAPSHOT</version> <name>DbProject</name> <url>http://maven.apache.org</url> <repositories> <repository> <id>com.example</id> <name>Example Repository</name> <url>http://192.168.11.1/dav/m2repo/</url> </repository> <repository> <id>maven.seasar.org</id> <name>The Seasar Foundation Maven2 Repository</name> <url>http://maven.seasar.org/maven2</url> </repository> </repositories> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.seasar.container</groupId> <artifactId>s2jdbc-gen</artifactId> <version>[2.4.38,)</version> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jpa_3.0_spec</artifactId> <version>[1.1.1,)</version> </dependency> <dependency> <groupId>org.apache.geronimo.specs</groupId> <artifactId>geronimo-jta_1.1_spec</artifactId> <version>[1.0,)</version> </dependency> <dependency> <groupId>org.seasar.container</groupId> <artifactId>s2-framework</artifactId> <version>[2.4.38,)</version> </dependency> <dependency> <groupId>org.seasar.container</groupId> <artifactId>s2-extension</artifactId> <version>[2.4.38,)</version> </dependency> <dependency> <groupId>org.seasar.container</groupId> <artifactId>s2-tiger</artifactId> <version>[2.4.38,)</version> </dependency> <dependency> <groupId>org.seasar.dao</groupId> <artifactId>s2-dao</artifactId> <version>[1.0.50,)</version> </dependency> <dependency> <groupId>postgresql</groupId> <artifactId>postgresql</artifactId> <version>8.3-603.jdbc4</version> </dependency> </dependencies> <build> <finalName>DbProject</finalName> <plugins> <plugin> <artifactId>maven-antrun-plugin</artifactId> <dependencies> <dependency> <groupId>org.apache.ant</groupId> <artifactId>ant</artifactId> <version>1.7.0</version> </dependency> </dependencies> <configuration> <tasks name="migrate"> <ant antfile="${basedir}/s2jdbc-gen-build.xml" inheritRefs="true"> <target name="${ant.target}" /> </ant> </tasks> </configuration> <goals> <goal>run</goal> </goals> </plugin> </plugins> </build> </project>
http://192.168.11.1/dav/m2repo/となってるところは、うちの環境で使ってるリポジトリ。ここは普通、一般に公開されているリポジトリを指定すればいいのかなー(  ̄− ̄)
pom.xmlと同じディレクトリに「s2jdbc-gen-build.xml」を以下のように作成。
<?xml version="1.0"?> <project name="s2jdbc-gen"> <target name="init"> <property name="version" value="latest" /> <property name="classpathdir" value="target/classes" /> <property name="rootpackagename" value="com.example.db" /> <property name="entitypackagename" value="entity" /> <property name="javafiledestdir" value="src/main/java" /> <property name="testjavafiledestdir" value="src/test/java" /> <property name="javafileencoding" value="UTF-8" /> <property name="env" value="ut" /> <property name="jdbcmanagername" value="jdbcManager" /> <taskdef resource="s2jdbc-gen-task.properties" classpathref="maven.runtime.classpath"> </taskdef> </target> <target name="gen-entity" depends="init"> <gen-entity rootpackagename="${rootpackagename}" entitypackagename="${entitypackagename}" javafiledestdir="${javafiledestdir}" javafileencoding="${javafileencoding}" env="${env}" jdbcmanagername="${jdbcmanagername}" classpathref="maven.runtime.classpath"> </gen-entity> </target> <target name="gen-ddl" depends="init"> <gen-ddl classpathdir="${classpathdir}" rootpackagename="${rootpackagename}" entitypackagename="${entitypackagename}" env="${env}" jdbcmanagername="${jdbcmanagername}" classpathref="maven.runtime.classpath" /> </target> <target name="migrate" depends="init"> <migrate classpathdir="${classpathdir}" rootpackagename="${rootpackagename}" entitypackagename="${entitypackagename}" applyenvtoversion="${applyenvtoversion}" version="${version}" env="${env}" jdbcmanagername="${jdbcmanagername}" classpathref="maven.runtime.classpath" /> </target> <target name="rollback" depends="init"> <migrate classpathdir="${classpathdir}" rootpackagename="${rootpackagename}" entitypackagename="${entitypackagename}" applyenvtoversion="${applyenvtoversion}" version="previous" env="${env}" jdbcmanagername="${jdbcmanagername}" classpathref="maven.runtime.classpath" /> </target> </project>
Eclipseで新規作成>「ソースフォルダ」へ行き、「src/main/resources」としてソースフォルダを追加。ここに以下の3つのファイルを作成
convention.diconはどこかのチュートリアルにあるやつをコピーして持ってきた。どこかで使うのかなー。でも内容は変更してない。。
convention.diconは以下の通り
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <component class="org.seasar.framework.convention.impl.NamingConventionImpl"> <initMethod name="addRootPackageName"> <arg>"examples"</arg> </initMethod> </component> <component class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/> </components>
jdbc.diconは以下の通り
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components namespace="jdbc"> <include path="jta.dicon" /> <component name="resultSetFactory" class="org.seasar.dao.pager.PagerResultSetFactoryWrapper"> <arg> <component class="org.seasar.extension.jdbc.impl.BasicResultSetFactory" /> </arg> <property name="useScrollCursor">true</property> </component> <component class="org.seasar.extension.jdbc.impl.ConfigurableStatementFactory"> <arg> <component class="org.seasar.dao.pager.PagerStatementFactory" /> </arg> <property name="fetchSize">100</property> </component> <component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl"> <property name="driverClassName">"org.postgresql.Driver"</property> <property name="URL"> "jdbc:postgresql://localhost:5432/testdb" </property> <property name="user">"test"</property> <property name="password">"test"</property> <initMethod name="addProperty"> <arg>"autoCommit"</arg> <arg>"true"</arg> </initMethod> </component> <component name="connectionPool" class="org.seasar.extension.dbcp.impl.ConnectionPoolImpl"> <property name="timeout">600</property> <property name="maxPoolSize">5</property> <property name="allowLocalTx">true</property> <destroyMethod name="close" /> </component> <component name="dataSource" class="org.seasar.extension.dbcp.impl.DataSourceImpl" /> </components>
s2jdbc.diconは以下の通り
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE components PUBLIC "-//SEASAR//DTD S2Container 2.4//EN" "http://www.seasar.org/dtd/components24.dtd"> <components> <include path="jdbc.dicon"/> <include path="s2jdbc-internal.dicon"/> <component name="jdbcManager" class="org.seasar.extension.jdbc.manager.JdbcManagerImpl"> <property name="maxRows">0</property> <property name="fetchSize">0</property> <property name="queryTimeout">0</property> <property name="dialect"> <component class="org.seasar.extension.jdbc.dialect.Postgre81Dialect" /> </property> </component> </components>
s2jdbc-gen-build.xmlにはとりあえず以下のタスクを追加してある
- gen-entity(DBのスキーマからエンティティクラスを生成)
- gen-ddl(エンティティクラスからDDLを生成)
- migrate(最新のDDLからスキーマを生成)
- rollback(ひとつ前のバージョンにスキーマを戻す)
コマンドラインから実行するには以下のようにする。
> mvn -Dant.target=gen-entity antrun:run
- Dant.target=の後に、s2jdbc-gen-build.xmlに書いたターゲットを指定すると、そのタスクを実行することができる。(ちょっとかっこ悪いけど。もっといい方法があるのかなー)
上記のコマンドを実行すると、com.example.dbパッケージにエンティティクラスが出来上がる。migrateとrollbackはバージョンを指定しても実行できるので、パラメータで渡すか、入力させるかしたほうがいいね。これはあとで考えよう。