かとじゅんの技術日誌

技術の話をするところ

XMLやSQLを極力書かないでよいO/Rマッパー S2Dao

S2Dao

Seasar2のプロダクトで初めて使ったのはS2Daoでした。
特徴にも書かれていることですが、小難しい設定用XMLもいらず、簡単なSQLなら自動生成と、ほんとらくらくにDBにI/OできるO/Rマッパーです。

Seasar2を使っている人は良く使っていると思いますが、流布のために簡単にご紹介します。


基本的にエンティティを表現するJavaBeansと、Dao(Data Access Object)を作るだけでOKです。

DB
CREATE TABLE USER_INFO(
	USER_ID		VARCHAR(16) NOT NULL PRIMARY KEY,	-- ユーザID(PK)
	PASSWORD 		VARCHAR(16) NOT NULL,		-- パスワード
	EMAIL_ADDRESS 	VARCHAR(64),			-- メールアドレス
	);
エンティティ
@Bean(table = "USER_INFO")
public class UserInfo {

	private String userId;

	private String password;

	private String emailAddress;

	public String getUserId() {
		return userId;
	}

	public String getEmailAddress() {
		return emailAddress;
	}

	public String getPassword() {
		return password;
	}

	@Column("USER_ID")
	public void setUserId(String userId) {
		this.userId = userId;
	}

	public void setEmailAddress(String emailAddress) {
		this.emailAddress = emailAddress;
	}

	public void setPassword(String password) {
		this.password = password;
	}

}
Dao
@S2Dao(bean = UserInfo.class)
public interface UserInfoDao {

	public int insert(UserInfo userInfo);

	public int update(UserInfo userInfo);

	public int delete(UserInfo userInfo);

	public List<UserInfo> selectAll();

	@Arguments("USER_ID")
	public UserInfo selectById(String userId);

}
Page(Daoを使うクラス)
public class HogeHogePage{

	private UserInfoDao userInfoDao;

	public void setUserInfoDao(UserInfoDao userInfoDao){
		this.userInfoDao = userInfoDao;
	}

	public String doLogin(){
		UserInfo userInfo = this.userInfoDao.selectById(this.userName);
<snip>
		return null;
	}

}

DaoとPageは、Seasar2コンポーネント登録しておく必要があります。そうするとHogeHogePageにDaoがDIされるようになります。
そのDaoは既に使える状態でDIされるので、必要なところでDaoのメソッドを呼び出してあげればよいだけです。
なにか気がつきましたか?そうインピーダンスミスマッチを埋める実装コードも、ごちゃごちゃとしたXML設定ファイルとか、それどころかSQLも書いてなかったりします。
これらも書くことが諸悪の根源かというとそうではなく、本質的に必要最低限の記述で済ませられるかどうかだと思います。それができるのがS2Daoです。
複数のテーブルをJOINしたり、検索条件が複雑なものはSQLの記述が必要になりますが、それも驚くぐらい簡単に記述できます。

public interface UserInfoDao {

	@Arguments("USER_ID")
	public UserInfo selectByIdWithLessEmailAddress(String userId);

}

SQLを指定したい場合は、Dao名_メソッド名.sqlSQLファイルを用意します。この場合、UserInfoDao_selectByIdWithLessEmailAddress.sqlです。
そのファイルには、

SELECT * FROM USER_INFO WHERE USER_ID = /*USER_ID*/'hogehoge' AND EMAIL_ADDRESS == NULL

と記述するだけです。非常に簡単です。(JOINしたければ好きにSQLをここに書けばよいことになります。ただし、結果を受け取るJavaBeansはちゃんと作る必要あります)

selectByIdWithLessEmailAddressの第一引数の値は、Argumentsアノテーションで指定したUSER_IDコメントの位置に置き換えられSQLが実行されます。
しかも、このSQL文はDBMS上のクライアントコンソールなどからコピペでそのまま検証ができます。

まぁ、これをプログラムロジック内部で組み立てた経験のある人は、メリットをきっと感じてくれるはず。そもそもバグの温床を作る余地がありません^^;
きちんとドキュメントやサンプルソースを読んでDaoを書けば誰でもシンプルなコードがかけます。シンプルであるということは何物にも代えがたいですね。


ちなみに、PHP5でもS2Daoが使えるようです。

http://s2dao.php5.seasar.org/