MyBatis + Guice でカンタン DAO 実装(その 1)
O/R マッパーである MyBatis と軽量 DI コンテナ Guice による DAO 実装について、今回から数回に分けて書きます。
MyBatis とは
MyBatis は iBatis の後継となる O/R マッパー。マッピングファイルに SQL を記述し、インターフェースを用意することで、マッピングファイルから自動的にインターフェースの実装をしてくれる。
Guice とは
Google が開発している Java 向けの軽量 DI コンテナ。DI は "Dependency Injection" の略で、日本語に訳すと「依存性の注入」。外部のオブジェクトに依存する部分を、実行時に外部から注入する仕組みで、オブジェクト間の依存関係をソースコードから排除し、オブジェクトの独立性を高め、単体テストをしやすくする。
下準備
今回使用するテーブルについて
データベースは MySQL を使用。
必要なライブラリ
- MyBatis
- mybatis-3.2.5.jar
- Guice*1
- guice-3.0.jar
- javax.inject.jar
- aopalliance.jar
- MyBatis + Guice 連携
- mybatis-guice-3.5.jar
- Velocity*2
- velocity-1.7.jar
- velocity-tools-2.0.jar
- commons-beanutils-1.9.1.jar
- commons-collections-3.2.1.jar
- commons-digester-1.8.1.jar
- commons-lang-2.6.jar
- commons-logging-1.1.3.jar
- JDBC ドライバ
DAO 層の実装
MyBatis の設定ファイル
まずは MyBatis の設定を mybatis-config.xml に記述する。ファイルはクラスパスの直下におくこと(Eclipse の動的 Web プロジェクトであれば、src フォルダの直下に置く)。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <typeAliases> <typeAlias type="jp.mydns.akanekodou.model.City" alias="City" /> </typeAliases> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/dbname" /> <property name="username" value="username" /> <property name="password" value="password" /> </dataSource> </environment> </environments> <mappers> <mapper resource="jp/mydns/akanekodou/dao/mapper/city-mapper.xml" /> </mappers> </configuration>
これは MySQL を使う場合の設定。dbname
, username
, password
は適宜書き換える。他の RDBMS を使う場合は JDBC ドライバの部分や接続 URL も変わってくるので、その部分も適宜書き換える。
Java Beans の記述
モデルとなる Java Beans の記述。
package jp.mydns.akanekodou.bean; import java.util.Date; public class City { private int id; private String name; private String pref; private Date designatedDay; private double area; private int population; private String dstName; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPref() { return pref; } public void setPref(String pref) { this.pref = pref; } public Date getDesignatedDay() { return designatedDay; } public void setDesignatedDay(Date designatedDay) { this.designatedDay = designatedDay; } public double getArea() { return area; } public void setArea(double area) { this.area = area; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } public String getDstName() { return dstName; } public void setDstName(String dstName) { this.dstName = dstName; } }
マッピングファイルの記述
マッピングファイルと、それによって実装されるインターフェースの記述。まずはインターフェースから。
package jp.mydns.akanekodou.dao.mapper; import java.util.List; import jp.mydns.akanekodou.bean.City; public interface CityMapper { List<City> all(); City find(int id); }
次にインターフェースを実装するためのマッピングファイル。CityMapper.java と同じパッケージ内に配置する。
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="jp.mydns.akanekodou.dao.mapper.CityMapper"> <resultMap id="cityResultMap" type="City"> <id property="id" column="city_id" /> <result property="name" column="city_name" /> <result property="pref" column="pref_name" /> <result property="designatedDay" column="designated_day" /> <result property="area" column="area" /> <result property="population" column="population" /> <result property="dstName" column="dst_name" /> </resultMap> <select id="all" resultMap="cityResultMap"> SELECT c.city_id as city_id, c.city_name as city_name, c.pref_name as pref_name, c.designated_day as designated_day, c.area as area, c.population as population, d.dst_name as dst_name FROM major_city c NATURAL JOIN district d ORDER BY city_id </select> <select id="find" parameterType="int" resultMap="cityResultMap"> SELECT c.city_id as city_id, c.city_name as city_name, c.pref_name as pref_name, c.designated_day as designated_day, c.area as area, c.population as population, d.dst_name as dst_name FROM major_city c NATURAL JOIN district d WHERE city_id = #{id} </select> </mapper>
次回、Guice を用いて DAO を実装する。