やってみよう part1(DBからデータ取得して表示まで)

昨日は、アプリ構築のためのDBまわりや、SAStrutsを使うための初期設定までを終えた。

ちなみに最終目的はスケジューラアプリを作るということ。あと別観点の目的として、

  • SAStrutsを社内のPJに導入すべきかどうかの見極め
  • Seam を勉強するための、事前勉強

というのもある。

さて、まずDBのデータをただ取得するだけの簡単なアプリを作ってみようと思う。

テーブルの構造

単純なユーザマスタと思ってもらえたらいい。
キーは単純なidとしている。login_idもユニークなんならキーにしちゃえばいいじゃんと思うけど、そこはそれ。サロゲートキーを使ってみました。ここは完全にid:habuakihiroさんの「楽々ERDレッスン」の影響を受けています。

エンティティ作成

root packageは"kizashi.scheduler"である。適当ですよ。

package kizashi.scheduler.entity;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.GeneratedValue;
import javax.persistence.Table;

@Entity
@Table(name="m_user")
public class User {
    @Id
    @GeneratedValue // create table 時に auto incrementを指定しているから
    public Integer id;
    public String loginId;
    public String passwd;
    public String lastName;
    public String firstName;
    public String mailAddress;
    public String birthday;
}

これ、自動生成してくんねえかなぁ。
ちなみにテーブル名の指定(@Table(name="m_user"))でハマった。最初は M_USER と書いていたらDBアクセス時にそんなテーブルねえよといわれたのだ。テーブル名は case sensitive ってことなのね。


Action その前に

http://localhost:8080/scheduler/manage
にアクセスすると、ユーザマスタのデータ一覧をHTMLのテーブルに表示する、みたいなイメージが目標である。

なので必然、クラス名は ManagerActionになる。JSP名はuserlist.jspとした。

package kizashi.scheduler.action;

import java.util.List;

import kizashi.scheduler.entity.User;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.struts.annotation.Execute;

public class ManageAction {

    public JdbcManager jdbcManager;
    public List<User> users;
    
	@Execute(validator = false)
	public String index() {
           users = jdbcManager.from(User.class).getResultList();
	    return "userlist.jsp";
	}
}

なんとあっさり。
JdbcManagerは宣言するだけで、DIしてくれる。

で、JSP

スタイルシートやらは省略。

<%@page pageEncoding="UTF-8"%>
<html>
<head>
<title>ユーザ一覧</title>
</head>
<body>
<html:errors/>
<s:form>
<table>
<c:forEach var="u" varStatus="s" items="${users}">
<tr>
  <td>${f:h(u.id)}</td>
  <td>${f:h(u.loginId)}</td>
  <td>${f:h(u.lastName)} ${f:h(u.firstName)}</td>
  <td>${f:h(u.mailAddress)}</td>
</tr>
</c:forEach>
</table>
</s:form>
</body>
</html>

ループはJSTLだけど、表示はELというのがちょっとアレなかんじ。
JSTLは慣れてるから使いやすいし、ELはかっこいいからちょうどいいかな、とも思う。

ちなみに、これで、もう完了です。
ちゃんとDB内のデータが表示されました。
これはいいわ。

忘れてはいけない。

http://localhost:8080/scheduler/

にアクセスされたときのことも考えておこう。ちゃんとガイドにも載っているがIndexActionをつくるのが正解。

package kizashi.scheduler.action;

import org.seasar.struts.annotation.Execute;

public class IndexAction {

	@Execute(validator = false)
	public String index() {
		return "index.jsp";
	}
}

かなり満足。

いや、これからである。

Strutsを生で作るときのお作法は、BaseActionというActionの親玉を作って、個別の実装は子Actionに書くというやり方である。
BaseActionの仕事は、

  • Template Methodパターンで前処理として「ログインチェック」「共通ログ出力」「トランザクション開始」なんかをする。
  • 後処理では「コミット(成功時)」「トランザクション終了」などで、各Actionからあがってきた例外に応じてエラー画面を振り分けたりもする(振り分け自体はstruts-config.xmlか?)。もちろん例外時は「ロールバック」処理もする。
  • その他、各Actionで共通で使いそうなメソッドを定義したりする。たとえば、
    • メッセージ処理系
    • ログ出力(ユーザIDをだせるように加工したりする)
    • セッションへのアクセスメソッド

なんかである。

Strutsに慣れているから、これをSAStrutsでやるとどうなるかというのを考えないといけない。
すぐにぶつかりそうな壁としては「ログインチェック」。これはログイン前はチェックしてはいけないし、ログイン後の画面遷移ではすべて共通的にしてやる必要がある。ま、当たり前だ。個別アクションでよびだされるActionのメソッドはバラバラだから、生Strutsのように、Template Method Pattern を使うわけにもいかんしなぁ。DI使ってうまくいけるかなぁ。

ちょっと考えてみよう。

ちなみにログ出力については、Seamでは@LoggerというアノテーションでloggerをDIしてくれる。これ、SAStrutsにもほしいなぁ。