S2Daoで複数データベースに繋いでやりくりする

以前、Seasar2のDIContainerを使ったコンポーネントとアスペクトの自動バインディングというエントリを書いて、 S2DaoでAspectAutoRegisterを使ってうんたらかんたらというのを実現したのですが、 2つのデータベースへの接続をする必要が出てきました。ということで。。     ■ データベースの作成

mysql> create database 20110706_1;
Query OK, 1 row affected (0.00 sec)
 
mysql> create database 20110706_2;
Query OK, 1 row affected (0.62 sec)
 
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| 20110706_1         |
| 20110706_2         |
~略~
+--------------------+
11 rows in set (0.00 sec)

    ■ テーブル作成 - データベース1

mysql> use 20110706_1
Database changed
mysql> create table hoge (id INT(11) NOT NULL AUTO_INCREMENT, hogehoge VARCHAR(64), PRIMARY KEY(id));
Query OK, 0 rows affected (0.10 sec)
 
mysql> show create table hoge;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                     |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| hoge  | CREATE TABLE `hoge` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `hogehoge` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

  - データベース2

mysql> use 20110706_2
Database changed
mysql> create table hage (id INT(11) NOT NULL AUTO_INCREMENT, hagehage VARCHAR(64), PRIMARY KEY(id));
Query OK, 0 rows affected (0.07 sec)
 
mysql> show create table hage;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                     |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| hage  | CREATE TABLE `hage` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `hagehage` varchar(64) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

    Eclipse せっかくなので最新版のEclipseを落としてみます。 http://www.publickey1.jp/blog/11/eclipseindigoguigui.html ↑によると、Eclipseは毎年6月にバージョンアップされるのですが、今年はIndigoってのが バージョン3.7としてリリースされたそうです。   特にJ2EEが~とかじゃないので、 http://www.eclipse.org/downloads/からEclipse IDE for Java Developersを落とします。 開発機は32bitのUbuntuを使ってるのでLinux 32 Bitを落とします。   ■ プロジェクト作成 New→Other→MavenMaven Project でMavenプロジェクトが作れるようになります。   リポジトリSeasarのを追加して、

<repository>
 <id>maven.seasar.org</id>
 <name>The Seasar Foundation Maven2 Repository</name>
 <url>http://maven.seasar.org/maven2
</repository>

  諸々依存のあるjarを追加します。

 <dependency>
 <groupId>log4j</groupId>
 <artifactId>log4j</artifactId>
 <version>1.2.16</version>
</dependency>

<dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>5.1.6</version>
</dependency>

<dependency>
 <groupId>org.seasar.container</groupId>
 <artifactId>s2-tiger</artifactId>
 <version>2.4.40</version>
</dependency>

<dependency>
 <groupId>org.seasar.dao</groupId>
 <artifactId>s2-dao</artifactId>
 <version>1.0.51</version>
</dependency>

<dependency>
 <groupId>org.seasar.dao</groupId>
 <artifactId>s2-dao-tiger</artifactId>
 <version>1.0.51</version>
</dependency>

<dependency>
 <groupId>org.apache.geronimo.specs</groupId>
 <artifactId>geronimo-j2ee_1.4_spec</artifactId>
 <version>1.0</version>
 <type>jar</type>
 <scope>provided</scope>
</dependency>

      ■ diconファイルの整備 app.dicon - includeとコンポーネントの登録 aop.dicon - interceptor系(デフォルトのまま) j2ee.dicon - j2ee1.diconとj2ee2.diconのinclude j2ee1.dicon - DB1への接続情報 j2ee2.dicon - DB2への接続情報 dao1.dicon - dao1っていう名前空間 dao2.dicon - dao2っていう名前空間   - コンポーネントの登録

<component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
 <property name="autoNaming">
  <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
 </property>
 <initMethod name="addClassPattern">
  <arg>"com.shinodogg.mulconn.dao.dao1"</arg>
  <arg>".*Dao"</arg>
 </initMethod>
</component>

<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
 <property name="interceptor">dao1.interceptor</property>
 <initMethod name="addClassPattern">
  <arg>"com.shinodogg.mulconn.dao.dao1"</arg>
  <arg>".*Dao"</arg>
 </initMethod>
</component>

<component class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
 <property name="autoNaming">
  <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
 </property>
 <initMethod name="addClassPattern">
  <arg>"com.shinodogg.mulconn.dao.dao2"</arg>
  <arg>".*Dao"</arg>
 </initMethod>
</component>

<component class="org.seasar.framework.container.autoregister.AspectAutoRegister">
 <property name="interceptor">dao2.interceptor</property>
   <initMethod name="addClassPattern">
  <arg>"com.shinodogg.mulconn.dao.dao2"</arg>
  <arg>".*Dao"</arg>
 </initMethod>
</component>

<component
 class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
 <property name="autoNaming">
   <component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
 </property>
 <initMethod name="addClassPattern">
   <arg>"com.shinodogg.mulconn"</arg>
   <arg>".*Job"</arg>
 </initMethod>
</component>

  - j2ee1.dicon

<component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
 <property name="driverClassName">"com.mysql.jdbc.Driver"</property>
 <property name="URL">"jdbc:mysql://localhost:3306/20110706_1"</property>
 <property name="user">"root"</property>
 <property name="password">""</property>
</component>
  • j2ee2.dicon
<component name="xaDataSource" class="org.seasar.extension.dbcp.impl.XADataSourceImpl">
 <property name="driverClassName">"com.mysql.jdbc.Driver"</property>
 <property name="URL">"jdbc:mysql://localhost:3306/20110706_2"</property>
 <property name="user">"root"</property>
 <property name="password">""</property>
</component>

  - dao1.dicon

~略~
<components namespace="dao">
 <include path="j2ee1.dicon"/>
 <component class="org.seasar.dao.impl.AnnotationReaderFactoryImpl"/>
~略~
  • dao2.dicon
~略~
<components namespace="dao">
 <include path="j2ee2.dicon"/>
 <component class="org.seasar.dao.impl.AnnotationReaderFactoryImpl"/>
~略~

    ■ いよいよコーディング - main文 Mavenプロジェクト作るとmain文持ったAppってクラスが出来るのでそのまま使います。。

public class App
{
    public static void main( String[] args )
    {
        App app = new App();
        app.execute();
    }

    private void execute() {
        SingletonS2ContainerFactory.setConfigPath("app.dicon");
        SingletonS2ContainerFactory.init();
        S2Container container = SingletonS2ContainerFactory.getContainer();
        displayBindingComponentAndAspect(container);
        Job job = (Job)container.getComponent("job");
        job.execute(container);
    }

    private void displayBindingComponentAndAspect(S2Container container) {
        for (int i = 0; i < container.getComponentDefSize(); i++) {
            String compName = container.getComponentDef(i).getComponentName();
            Class className = container.getComponentDef(i).getComponentClass();

            if (compName != null && className != null) {
                System.out.println("コンポーネント名 : " + compName + " : クラス名 : "
                        + className.toString());
                int aopSize = container.getComponentDef(i).getAspectDefSize();
                for (int j = 0; j < aopSize; j++) {
                    System.out.println(" AOP : "
                            + (j + 1)
                            + " : "
                            + container.getComponentDef(i).getAspectDef(j)
                                    .getAspect().getMethodInterceptor()
                                    .getClass().getName());
                }
            }
        }
    }
}
  • DBとやり取りするAction
public class Job
{
    public HogeDao hogeDao; ★ インジェクションされるフィールド ★
    public HageDao hageDao; ★ インジェクションされるフィールド ★

    public void execute(S2Container container) {
        System.out.println("Hoge: " + ((List)hogeDao.getAllHoges()).size());
        System.out.println("Hage: " + ((List)hageDao.getAllHages()).size());

        // ★ 今日はタイムアップ明日これ使ってちゃんと実装しる。。。★
        TransactionManager transactionManager1 = (TransactionManagerImpl) container.getComponent("transactionManager1");
        TransactionManager transactionManager2 = (TransactionManagerImpl) container.getComponent("transactionManager2");
    }
}
  • Dao(1個目のDBに繋がるヤツ)
package com.shinodogg.mulconn.dao.dao1;
~略~
@S2Dao(bean = Hoge.class)
public interface HogeDao {
    public List getAllHoges();
}
  • Dao(2個目のDBに繋がるヤツ)
package com.shinodogg.mulconn.dao.dao2;
~略~
@S2Dao(bean = Hage.class)
public interface HageDao {
    public List getAllHages();
}
  • Entity
@Bean(table="hoge")
public class Hoge {
    public long id;
    public String hogehoge;
}
@Bean(table="hage")
public class Hage {
    public long id;
    public String hagehage;
}

    ■ 実行すると、、、 それっぽくなりました、と。

コンポーネント名 : hogeDao : クラス名 : interface com.shinodogg.mulconn.dao.dao1.HogeDao
 AOP : 1 : org.seasar.dao.pager.PagerS2DaoInterceptorWrapper
コンポーネント名 : hageDao : クラス名 : interface com.shinodogg.mulconn.dao.dao2.HageDao
 AOP : 1 : org.seasar.dao.pager.PagerS2DaoInterceptorWrapper
コンポーネント名 : job : クラス名 : class com.shinodogg.mulconn.Job
Hoge: 3
Hage: 5
mysql> use 20110706_1
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from hoge;
+----+----------+
| id | hogehoge |
+----+----------+
|  1 | a        |
|  2 | b        |
|  3 | c        |
+----+----------+
3 rows in set (0.02 sec)

mysql> use 20110706_2
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from hage;
+----+----------+
| id | hagehage |
+----+----------+
|  1 | a        |
|  2 | a        |
|  3 | a        |
|  4 | a        |
|  5 | a        |
+----+----------+
5 rows in set (0.00 sec)

    ■ 明日は、、 トランザクションがきちんと管理できることを検証する予定です。  

Seasar 2 徹底入門 SAStruts/S2JDBC 対応
竹添 直樹
翔泳社
売り上げランキング: 9213