やってみよう part1(DBからデータ取得して表示まで)
昨日は、アプリ構築のためのDBまわりや、SAStrutsを使うための初期設定までを終えた。
ちなみに最終目的はスケジューラアプリを作るということ。あと別観点の目的として、
というのもある。
さて、まず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にもほしいなぁ。