ユーザ情報テーブルでのHibernate利用

はじめに、ユーザ情報テーブルに対して、Hibernateを利用してO/Rマッピングを作成してみましょう。

JPAにおいては、基本的には、 1つのJavaクラスを1つのテーブルに対応させ、 そのクラス内のプロパティ、setterメソッド(set(プロパティ名))、getterメソッド(get(プロパティ名))をテーブル内のカラムと対応させる必要があります。
WEBアプリケーション開発フレームワーク で作成したstruts2todoプロジェクトに対して、以下のような構造で作成するものとします。


Hibernateを使用可能にする

まず、Hibernate関連のファイルをダウンロードし、プロジェクトのクラスパスに追加しましょう。

  1. 以下のファイルをダウンロードし、適当なディレクトリに展開してください。

    ダウンロード hibernate-distribution-3.3.1.GA-dist.zip hibernate-entitymanager-3.4.0.GA.zip slf4j-1.5.6.zip


  2. Struts2に関連するJARファイルをWEB-INF/libにコピーします。
    さきほど展開したzipファイルから以下のファイルをWEB-INF/libにコピーしてください。

    • hibernate-distribution-3.3.1.GA-dist.zip内のlib\required\antlr-2.7.6.jar
    • hibernate-distribution-3.3.1.GA-dist.zip内のlib\required\commons-collections-3.1.jar
    • hibernate-entitymanager-3.4.0.GA.zip内のhibernate-entitymanager.jar
    • hibernate-entitymanager-3.4.0.GA.zip内のlib/*.jar(ただしslf4j-api.jarは除くこと)
    • slf4j-1.5.6.zip内のslf4j-api-1.5.6.jar
    • slf4j-1.5.6.zip内のslf4j-jdk14-1.5.6.jar


  3. struts2todoプロジェクトを右クリックし「Properties」を選択し、「Java Build Path」に 前記で追加したWEB-INF/lib以下のJARファイルを設定してください。

    これで、JavaプログラムからJARファイル内にあるクラスを参照可能になります。

アノテーションの追加

Javaクラスにアノテーションを追加していきます。
アノテーションとは、@から始まる文字列をクラス定義やメンバ定義に付加することで、クラスやメンバに追加情報を定義する手法です。

JPAでは、以下のようなアノテーションを定義することができます。

アノテーション 対象 意味
javax.persistence.Entity クラス定義 クラスが永続化可能であることを明示します。
javax.persistence.Table
(name=(テーブル名))
クラス定義 クラスが対応しているテーブルを明示します。
javax.persistence.Id メンバ定義 メンバがIDであることを明示します。
javax.persistence.Column
(name=(テーブル名))
メンバ定義 メンバが対応しているカラムを明示します。


test.Userクラスを以下のように修正します。

ダウンロード User.java

6~8行目:
  6: @javax.persistence.Entity
  7: @javax.persistence.Table(name = "TODO_USER")
  8: public class User {

UserクラスがTODO_USERと関連づいたクラスであることの宣言。
JPAのアノテーションルールに従って、「@(アノテーション情報)」の形式で情報を付加します。
39~41行目:
 39: @javax.persistence.Id
 40: @javax.persistence.Column(name = "ID")
 41: public String getId() {

IdプロパティがIDであることと、カラム名がIDであることの宣言。
59~60行目:
 59: @javax.persistence.Column(name = "NAME")
 60: public String getName() {

Nameプロパティに対応するカラム名がNAMEであることの宣言。
同様に、Passwordプロパティに関しても定義をおこないます。

Actionクラスの修正

データベースからのデータ取得処理をJPAを利用する形に修正していきます。
データベースからデータを取得するためには、Hibernateが提供するjavax.persistence.EntityManagerオブジェクトを利用します。
具体的には、以下のメソッドを使用してデータベースからオブジェクトを取得する処理を実装します。

機能 実現方法
EntityManagerの取得 javax.persistence.Persistenceとjavax.persistence.EntityManagerFactoryを使用する。
EntityManagerFactory Persistence.createEntityManagerFactory((設定名))を呼び出し
EntityManagerFactoryを取得後、
EntityManager EntityManagerFactory.createEntityManager()を呼び出しEntityManagerを取得する。
設定名は後述するpersistence.xmlに記述したものを指定する。
オブジェクトの取得 javax.persistence.Query EntityManager.createQuery(String)を使用する。
第1引数にはJPQLで記述したクエリを指定し、Query.getResultList()により
クエリに該当するオブジェクトを取得することができる。


また、JPQLは以下のような形式で記述することができます。

機能 用例 実現方法
テーブル中の全データの取得 SELECT u FROM User u SELECT (変数名) FROM (クラス名) (変数名)の形式で記述する。
クラス名には永続化クラス名を指定し、変数名2箇所は同じにする必要がある。
テーブル中の特定データの取得 SELECT u FROM User u WHERE u.id='テスト' SELECT (変数名) FROM (クラス名) (変数名) WHERE (条件文)の形式で記述する。
条件文には「(変数名).(プロパティ名)」のような形式でカラムを指定したり、
定数を指定したりすることができる。


Actionクラスを、JPAが提供するjavax.persistence.EntityManagerクラスを利用するように修正します。

ダウンロード LoginAction.java AbstractDBAction.java AddAction.java DeleteAction.java EditAction.java FinishAction.java

144~151行目:
144: protected EntityManager getEntityManager() {
145:     if (_entityManager == null) {
146:         EntityManagerFactory factory = Persistence
147:                 .createEntityManagerFactory("sample");
148:         _entityManager = factory.createEntityManager();
149:     }
150:     return _entityManager;
151: }

EntityManagerを取得する処理。
後述する設定ファイルに記述された設定名(今回は"sample")をキーとしてEntityManagerを取得します。
160~169行目:
160: protected User queryUser(String userID) {
161:     EntityManager entityManager = getEntityManager();
162:     Query query = entityManager.createQuery("SELECT u FROM User u WHERE u.id='"
163:             + userID + "'");
164:     List users = query.getResultList();
165:     if(users.size() == 0) {
166:         return null;
167:     }
168:     return (User) users.get(0);
169: }

EntityManagerから特定のIDを持つUserを取得する処理。
JPQLをクエリとしてUserオブジェクトの取得をおこないます。
177~182行目:
177: protected User[] queryUsers() {
178:     EntityManager entityManager = getEntityManager();
179:     Query query = entityManager.createQuery("SELECT u FROM User u");
180:     List users = query.getResultList();
181:     return (User[])users.toArray(new User[0]);
182: }

EntityManagerから全Userを取得する処理。


設定ファイルの作成

設定ファイルを作成します。

WEB-INF/src/META-INF以下にpersistence.xmlを作成します。
ここでは、データベースの情報などを指定します。

ダウンロード persistence.xml

7~9行目:
  7: <class>
  8:     test.User
  9: </class>

Userクラスを永続化することの宣言。
10~16行目:
 10: <properties>
 11:     <property name="hibernate.connection.username" value="sa"/>
 12:     <property name="hibernate.connection.password" value=""/>
 13:     <property name="hibernate.connection.driver_class" value="org.h2.Driver"/>
 14:     <property name="hibernate.connection.url" value="jdbc:h2:tcp://localhost/~/test"/>
 15:     <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
 16: </properties>

接続対象のデータベースに関する宣言。
H2 Databaseに接続することを指定しています。
dialectとは、データベース間のSQLにおける方言を吸収するためのクラスです。接続するデータベースにより、この指定を変更する必要があります。

ここまでのファイル

ここまででプロジェクトディレクトリの内容は以下のようになります。
正しく作成できているか、確認してください。

ダウンロード struts2todo_1.zip


デバッグ

ブラウザで以下のURLを開きます。
http://localhost:8080/struts2todo/login.action