2009年12月24日木曜日

spring/iBATIS/Eclipse/Maven2

巷の案件情報を調べてみると、意外と iBATIS を使っている開発プロジェクトが多い。Java 業界では、もうとっくに Hibernate × JPA で決着がついたような気がしていたけど、気のせいだったか。 というわけで、復習ついでに Getting Started 的レシピを書いてみる。 ■ 前提
  • Eclipse 3.5 Galileo
  • m2eclipse 0.98 (Maven 2.2.1)
  • MySQL 5.0.45
■ データベースの準備 MySQL の`test`データベースに以下のようにテーブル`t1`を作り、データを入れる。
mysql> use test;
mysql> create table t1 (c1 int primary key, c2 varchar(20));
mysql> insert into t1(c1, c2) values (1, 'Hello, world!');
mysql> select * from t1;
+----+---------------+
| c1 | c2            |
+----+---------------+
|  1 | Hello, world! |
+----+---------------+
■ プロジェクト作成
  • maven-archetype-quickstart 1.0を用いて、Eclipse で Maven Project を作成。artifactId 等、適当でかまわないが、ここでは以下のようにした。
    groupIdnet.yasuabe.studies.spring
    artifactIdspring-ibatis
    version0.0.1-SNAPSHOT
    packagenet.yasuabe.studies.spring.spring_ibatis
  • pom.xml に以下の依存を追加(バージョン等は今日の日付で最新のもの)。
    groupIdartifactIdversion
    org.springframeworkspring-orm3.0.0.RELEASE
    org.springframeworkspring-ibatis2.0.8
    commons-dbcpcommons-dbcp1.2.2
    mysqlmysql-connector-java5.1.10
    JUnit 3.8 を dependency から削除し、src/test/java 下の AppTest.java も削除する。
  • 新規ソースフォルダとして、src/main/resources を作成する。ここに *.xml を置く。
以上、spring + iBATIS の大体の共通作業。 ■ プログラムを書く 続いて上記設定の疎通確認ができるようなプログラムを書いてみる。
  • こんなエンティティクラスに、RDB テーブル`t1`のレコードをマッピングする。
    package net.yasuabe.studies.spring.spring_ibatis;
    
    public class T1 {
       private int c1;
       private String c2;
       ・・・ getter / setter 略
    }
  • また、RDB テーブル`t1`への操作を以下のように T1Dao で宣言する。
    package net.yasuabe.studies.spring.spring_ibatis;
    
    import java.util.List;
    
    public interface T1Dao {
        public List<T1> selectAll();
    }
  • これらのマッピングと操作を以下のように T1.xml にて記述する。
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-2.dtd">
    
    <sqlMap>
        <typeAlias type = "net.yasuabe.studies.spring.spring_ibatis.T1" alias = "t1"/>
        <resultMap class = "t1" id = "result">
            <result property = "c1" column = "c1"/>
            <result property = "c2" column = "c2"/>
        </resultMap>  
        <select id = "selectAll" resultMap = "result">
            select c1, c2 from T1
        </select>
    </sqlMap>
  • この T1.xml を使うことを iBatis に知らせるために、以下のように SqlMapConfig.xmlを書く
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE sqlMapConfig
    PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
    
    <sqlMapConfig>
        <sqlMap resource="./T1.xml" />
    </sqlMapConfig>
  • この SqlMapConfig.xml と、iBatic および Spring を関連付けるために、以下のように spring-ibatis.xml を書く。
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
       <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close">
          <property name="driverClassName">
             <value>com.mysql.jdbc.Driver</value>
          </property>
          <property name="url">
             <value>jdbc:mysql://localhost/test</value>
          </property>
       </bean>
       <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
          <property name="configLocation">
             <value>./SqlMapConfig.xml</value>
          </property>
       </bean>
       <bean id="t1Dao" class="net.yasuabe.studies.spring.spring_ibatis.T1DaoImpl">
          <property name="dataSource">
             <ref local="dataSource" />
          </property>
          <property name="sqlMapClient">
             <ref local="sqlMapClient" />
          </property>
       </bean>
    </beans>
    この spring-ibatis.xml では、SqlMapConfig.xml の指定の他に、データソースの指定と、t1Dao 実装クラスへのそれらのインジェクションも記述している。
  • bean定義 t1Dao の class に指定されている T1DaoImpl は、T1Dao の実装クラスで以下のようなものになる。
    package net.yasuabe.studies.spring.spring_ibatis;
    import ・・・略
    
    public class T1DaoImpl extends SqlMapClientDaoSupport implements T1Dao {
       @Override
       public List<T1> selectAll() {
            SqlMapClientTemplate template = getSqlMapClientTemplate();
            return (List<T1>)template.queryForList("selectAll");
       }
    }
    (プロパティ dataSource と sqlMapClient は、基底クラス SqlMapClientDaoSupportで定義されている)
これでエンティティと Dao の準備ができたのでクライアントコードを書いてみる。アーキタイプ が既に App.java を作っているはずなので、その main() を書き換える。
public static void main(String[] args) {
   Resource resource = new ClassPathResource("/spring-ibatis.xml");
   BeanFactory beanFactory = new XmlBeanFactory(resource);

   T1Dao t1Dao = (T1Dao) beanFactory.getBean("t1Dao");
   for (T1 t1: t1Dao.selectAll()) {
      System.out.printf("c1:%d c2:%s%n", t1.getC1(), t1.getC2());
   }
}
■ 実行 こんなコンソール出力を得る。
c1:1 c2:Hello, world!
割と簡単だった。

1 件のコメント:

師子乃 さんのコメント...

こんにちは。

10年以上たった今でもmyBatisを使っているところはありますね。

コメントを投稿