つかびーの技術日記

情報系修士卒のWeb系技術日記です。現在のフォーカス分野はアドテクです。

Wicket + MyBatis + Guice (+ Maven)でおk

      2013/09/15

世の中には様々な言語とフレームワーク(FW)があるので、Webアプリケーションと言ってもその作り方は百通り以上あると思います。今回はJava使いの自分が「多分このやり方が一番楽だろう」という方法を書いて行きます。

タイトルと似たような記事は既に存在して、例えば以下のようなものがあります。

けど、微妙に情報が古かったりして少し手間取ったので自分でやってみた結果をここに書いておきます。

Wicket

JavaでWebアプリケーションを作るときに、個人的に一番厄介だと思うのがMVCでいうVです。Vは大抵JSPで書かれます。なまじJavaが書けちゃうもんだから、そこにめっさ処理を記述する場合があります。「そんなことないよ、あくまで表示のための処理だけを書くんだよ」と分かっていても、コーダが自分じゃないことはよくあるし、そしてM,Cの設計が残念な場合、Vもそれにつられて残念になることがあります。HTMLとJavaでごっちゃになってて見づらかったり、IDEの支援がフルに受けられなかったりもするし・・・。

というわけでVにHTMLがそのまま使えるWicketを採用します。

Wicketを知らない人は以下のWicket公式HelloWorldを見ればいいと思います。wicket:id=””をHTMLに書いて、後はJavaのWebPageを継承したクラスで対応するものを埋め込むだけです。

http://wicket.apache.org/learn/examples/helloworld.html

簡単だし、見やすいし、何よりHTMLをHTMLとして見れるのが良いです。JSPみたいに変に混ざってない。そんな訳でWicketを採用します。

MVCのM,CとMyBatis

VはWicketでやることにしましたが、M,Cはどうすればよいのか・・・。個人的にはMもCも確かに重要だけど、普通にJavaのコード書くだけでOKな気がしています。FWの支援はそこまでいらないのでは?と。

しかし、最低限、使う場所が多くて似たようなコードが多くなるDB処理とDBに依存するMは何とかしたい!そこで当たり前ともいえるO/Rマッパーを利用します。これにはMyBatisを採用します。

Hibernateも確かに便利だと思うけど、いかんせんSQLが見えないと怖いし学習コストも高い。そんな訳でMyBatisを採用します。

MyBatisはHibernateと比べてテーブル間の結合のサポートがないけど、そこは別にDBのVIEW(ストアドクエリ)で大丈夫です。DBとJavaのオブジェクトの同期化もないけど、それは別にいらないような気がしています。普通にMyBatisでupdateなり、deleteなりすればいいし、Hibernateのcommitよりはエンジニアにやさしい気がします。だってupdateとかいうメソッドの方が可読性高いでしょ、きっと。

Guice

なくてもいいけど、あると少し便利です。少しコードの記述が減ります。@Transactionalで例外発生したら自動rollbackとかも便利です。

Maven

慣れたり、概要把握に1週間くらいかかると思うけど、なかなか良いツールです。

使いたいjarがあったらMaven Centralで検索してヒットしたdependencyをpom.xmlに書いてプロジェクト更新。そうすればコード上でjarが利用できるようになります。

別にこれだけならjarを普通にDLしてlibフォルダなりに入れておけばそれでもOKだけど、その場合jarはプロジェクト配下に存在することになって個人的には微妙。gitなりsvnにjarも配置されてしまってサイズが大きくなってしまいます。

コード

前置きはほどほどにしてタイトルに挙げたものを使って簡単なWebアプリを作ります。

要件

  1. ページはTopPageの1ページのみ
  2. ページにアクセスすると自分のIPと1つ前の過去にアクセスした日時を表示する
  3. DBに自分のIPアドレスと現在のアクセス日時を記録する

前提

  1. Pleiades (All in One Eclipse)
  2. MyBatis Generator Plugin
  3. ERMaster Plugin

2と3はオプションだけど、おすすめPluginなのであったほうが良いです。

Eclipseプロジェクト作成

Mavenプロジェクトを新規作成します。

wicket_archtype-quickstart

wicket-archtype-quickstartを選択します。しかし、quickstartのバージョンが古いので、カタログを取り込むことにします。

[ウインドウ] -> [設定] -> [Maven] -> [リモート・カタログの追加]で「http://repo1.maven.org/maven2/archetype-catalog.xml」を追加。以下が参考になります。これでquickstartのverが6.10.0になりました。

http://tak-shimiz.lolipop.jp/oyajinote/blog/archives/2011/1115_191057.html

DB作成

DBなどをMySQLに作成します。

テーブルはERMasterで作成します。もちろん手で書いたり、他のツールを使っても良いです。

Maven追記

pomを変更。一部不要な記述を消して、今回利用するjarを追記します。

MyBatis準備

プロジェクトのルートフォルダにgeneratorConfig.xmlを作成します。もちろんmysql-connectorのパスやDBパスワードは適宜変更します。

これを実行すると以下ができます。これだけでDBに関するエンティティはもうOKです。

  • Access.java
    JavaBeanパターンのエンティティ。DTO。ようするにただのデータ構造でDBのレコード。
  • AccessMapper.java
    DAO。インタフェース。これに対応する実装クラスは生成されないが、問題無し。XMLを見ればよい。今回はこのインタフェースにGuiceで実装クラスのインスタンスを注入し、DB操作を可能にする。
  • AccessMapper.xml
    SQL。AccessMapperの実装。既にいくつかSQLが記述されている。足りない場合は自分で記述するが、今回はしない。
  • AccessExample.java
    AccessMapperに食わせる引数のクラス。SQLで言うWHERE句の検索条件など。

resourcesフォルダにmybatis-config.xmlを作成します。

database.propertiesを作成して、上記のDB設定を記述します。

Guice, MyBatis連携

現状のままだと、GuiceはMyBatisを知らないので、MyBatisのオブジェクトを注入しようとしてもできません。(@Injectとか使えない)

なので、こういうときはGuiceの設定を行います。

WicketApplication.javaのinitを以下のように変更。

WebPageとService作成

準備が整ったので、今回の目的のページと機能を作成します。まずはページから。com.tsukaby.wicket_mybatis_guiceにTopPageを作成します。

WicketApplication#getHomePageも変更しておきます。今回作成したTopPageをホームとします。

これだけでも動きますが、画面上に「あなたのIP: IP 前回のアクセス日時 ACCESS」と表示されるだけで全く意味がないです。そこで、次にIPとACCESSの部分を取得するロジック部分を作成します。

ここからMyBatisとGuiceに登場してもらいます。

まずAccessService.javaを作成します。Objectが継承元の普通のクラス。

次にこれをTopPageの方で利用するように変更します。

以上で完了。

コンストラクタ内だからsvcはまだInjectされてないのでは?使えないのでは?と思うけど、そこはwicket-guice連携のおかげなのか何とかなっている。理由までは不明です。

後、冒頭に挙げた参照先ではweb.xmlを変更してGuiceFilterとかを追加していますが、今回はそれをやらないでもInjectは成功しました。本当に必要な設定なのかはまた今度調べたい。

実際にアクセスしてみると以下のようになります。

wicket_mybatis_guice_toppage

wicket_mybatis_guice_db

IPがv6形式で表示されてしまう場合は、ぐぐれば分かりますがVM引数に「-Djava.net.preferIPv4Stack=true」を指定すればIPv4形式になります。

完成したアプリは以下に配置してみました。誰かの参考になれば幸いです。

http://tsukaby.com/WicketMyBatisGuice/

 - Java , ,