82.Daoの作り方サンプル(IBatis)
概要
Spring トランザクションはかなり強力で便利な機能です。
しかし、使用に関してはSpringトランザクションが働くようにDaoを作る必要があります。
前回の記事で通常の方法(SpringJDBCを使用する方法)を見ました。
ここではIBatisを使用する方法を見ます。
目標
まずは、ゴールを示しておきます。
会員の検索、更新などをするDaoを作ります。
(前回の記事とやることは同じですので、違いが見やすいかと思います。)
サンプル
【Daoのサンプル】
public class MemberDaoTestIbatis extends SqlMapClientDaoSupport {
//selectサンプル
public List<Member> findMember(MemberSearchKey searchKey) {
//会員リスト
List<Member> memberList = this.getSqlMapClientTemplate().queryForList(
"member.findMember", searchKey
);
return memberList;
}
//更新サンプル(insertも同じ)
public void updateMember(Member member){
Assert.hasText(member.getId());
this.getSqlMapClientTemplate().update(
"member.updateMember", member
);
}
}
メインのDaoサンプルクラスです。
ポイントは、SqlMapClientDaoSupportを継承することです。
これによりSpringトランザクションを使用できるようになります。
<getSqlMapClientTemplate>
このメソッドもSpringトランザクションを使用する上では重要です。
必ずこのメソッドで返されるテンプレートを使用してSQLを実行します。
そうしないと、うまくトランザクションが掛からないことがあります。
後は、通常のIBatisを使用するのと変わりません。
SQL例外をtry~catchする必要がないことも注目しておきましょう。
地味ですが、かなり楽になります。
【IBatisファイル: /dao/SqlMapConfig.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd" >
<sqlMapConfig>
<!-- 全体の設定
-->
<settings
cacheModelsEnabled="false"
classInfoCacheEnabled="true"
lazyLoadingEnabled="false"
enhancementEnabled="false"
/>
<!-- sqlMapファイル参照する -->
<sqlMap resource="dao/SqlMap-MemberDaoTest.xml"/>
</sqlMapConfig>
特に特筆することはありません。
普通のIBatisのConfigファイルです。
【IBatisファイル: /dao/SqlMap-MemberDaoTest.xml】
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="member">
<!-- 検索 -->
<select id="member.findMember" resultMap="member" parameterClass="business.domain.searchkey.MemberSearchKey">
select * from t_member
<dynamic prepend="WHERE">
<isNotEmpty prepend="AND" property="id">
id = #id#
</isNotEmpty>
<isNotEmpty prepend="AND" property="name">
name = #name#
</isNotEmpty>
<isNotEqual prepend="AND" compareProperty="ageFrom" compareValue="-1">
<![CDATA[
age >= #ageFrom#
]]>
</isNotEqual>
<isNotEqual prepend="AND" compareProperty="ageTo" compareValue="-1">
<![CDATA[
age <= #ageTo#
]]>
</isNotEqual>
</dynamic>
</select>
<!-- 更新 -->
<update id="member.updateMember" parameterClass="business.domain.Member">
update t_member set
name = #name#,
age = #age#
where
id = #id#
</update>
</sqlMap>
これも通常のIBatisの設定ファイルですので特筆することはありません。
【Memberクラス】
public class Member {
private String id;
private String name;
private int age;
//getter / setterを以下に書く(ここでは省略)
:
}
【MemberSearchKeyクラス (検索のキーワードクラス)】
public class MemberSearchKey {
private String id;
private String name;
private int ageFrom=-1;
private int ageTo=-1;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAgeFrom() {
return ageFrom;
}
public void setAgeFrom(int ageFrom) {
this.ageFrom = ageFrom;
}
public int getAgeTo() {
return ageTo;
}
public void setAgeTo(int ageTo) {
this.ageTo = ageTo;
}
}
【Spring Context ファイル (宣言的トランザクションの記事を参照)】
<!-- Data Source (例えばPostgres)-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql://localhost/XXXX" />
<property name="username" value="XXX" />
<property name="password" value="XXX" />
</bean>
<!-- iBatisの設定 -->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:/dao/SqlMapConfig.xml"/>
</bean>
<!-- DAO -->
<bean id="memberDaoTest" class="dao.MemberDaoTestIBatis">
<property name="sqlMapClient" ref="sqlMapClient" />
</bean>
<!-- トランザクション管理 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- 宣言的トランザクションの織り込み -->
<aop:config proxy-target-class="false">
<aop:advisor pointcut="execution(* business.service.*(..))" advice-ref="txAdvice" />
</aop:config>
<tx:advice id="txAdvice" >
<tx:attributes>
<tx:method name="find*" read-only="true" />
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>
宣言的トランザクションの記事と同じです。ほぼ再掲です。
SqlMapClientFactoryBeanの設定は、IBatis特有のものです。
設定ファイルのパスを設定するくらいですので、特筆することはありません。
これで、IBatisを使用するときのトランザクション制御をするときのDaoの作り方がわかったでしょうか?
トランザクションの記述については前回の記事と変わっていないことも見ていただければと思います。
さらに詳細な内容については、以下の記事をご覧ください。
Created Date: 2010/01/12