Hibernate入門(Hibernate3)
挿入,選択,更新,削除を行う単純なサンプルを作成し,Hibernateの概要を掴んでみる.
HibernateはO/Rマッピングツールと呼ばれ,設定ファイルに記述した内容によって,RDBとJavaオブジェクトのマッピングを行う.
Javaオブジェクトは自作する必要があるが(※),それをRDBに格納するための仕組み(SQL生成も含む)はO/Rマッピング情報によりHibernateが自動的に行ってくれる.
生成するSQLは上質で,本家はHigh Performanceを自認している.
※ Hibernate2ではhbm2javaという,設定ファイルからJavaコードを生成するツールがあるが,Hibernate3にはまだ見当たらない.
基本を押えつつ最も簡単であることを目指したサンプルを作成した.
これ.
サンプルの実行方法は以下.
$ tar zxvf HelloHibernate-0_01.tar.gz $ ant init $ ant preparelib DB構築 conf/create_table.sqlを使用してテーブル作成 filter.propertiesを編集(FILL MEと書いてある部分) $ ant runant preparelibではhttpでhibernate3とポスグレ用JDBCドライバをダウンロードし,展開するが,httpプロキシに対応していない. つまりうまくダウンロードできない場合はWebブラウザなどから以下をダウンロードする. また,ポスグレ以外のDBを使用する場合別途自力でJDBCドライバを用意されたい. ant runすると,DBアクセスしてレコードの追加,選択,更新,削除をして終了しているようなログが出る. 詳細は後述.
上記サンプルのようなHibernateを使用してDBアクセスを行うJavaアプリケーションを開発する場合,以下のような作業が必要であった.
- hibernate.cfg.xmlファイルの作成
- Hibernateの最も基本的な設定を記述する設定ファイル. HibernateがDBにアクセスする際に使用するDBの情報や,下記hbm.xmlファイルの指定を記述する.
- hbm.xmlファイルの作成
- O/Rマッピングを記述したファイル
- POJO(Plain Old Java Object)クラスの作成
- POJOは文字通り「普通の」Javaクラスのオブジェクトである. hbm.xmlファイルで指定したクラス,フィールド,フィールドに対するsetter,getterをもつ.
- DBアクセスのコーディング
- POJOは文字通り「普通の」Javaクラスのオブジェクトである. hbm.xmlファイルで指定したクラス,フィールド,フィールドに対するsetter,getterをもつ.
- Hibernateで提供されている仕組みを利用して,DBのデータからオブジェクトを生成したり,オブジェクトデータをDBに格納,更新したり,削除したりする.
サンプルのhibernate.cfg.xmlを以下に示す.
上記ではルート要素hibernate-configurationは一つのsession-factory要素をもつ.
これはDBとのセッションを作成する際の設定を表し,子要素にて以下の設定をしている.
- show_sql
- 発行するSQLをログ出力するか否か.
- dialect
- SQLのDB依存部分を隠蔽するための設定. サンプルはPostgreSQLを想定しているのでorg.hibernate.dialect.PostgreSQLDialectとした.
- hibernate.connection.driver_class
- JDBCドライバクラス.
- hibernate.connection.url
- DB接続時のURL.
- hibernate.connection.username
- DB接続時のユーザ名.
- hibernate.connection.password
- DB接続時のパスワード.
- mapping
- O/Rマッピング設定ファイルのパス. 設定ファイルの内容については次節にて記述する.
hibernate.cfg.xmlの要素mappingで記述したように,サンプルのO/RマッピングファイルはSimpleMessage.hbm.xmlである.
どうやらファイル名は
このマッピングファイルでO/RマッピングしているR側すなわちDBのテーブルは以下である.
DBとマッピングしている属性のsetter,getterが合致しているかどうかに注意する.
Javaクラス名.hbm.xmlのようなスタイルにする慣習のようだ. サンプルのSimpleMessage.hbm.xmlを以下に示す.
CREATE TABLE simplemessage( id INTEGER PRIMARY KEY, message TEXT NOT NULL );これを踏まえてマッピングファイルを見てみる. まずルート要素はhibernate-mappingである. 次に上記テーブルsimplemessageをオブジェクトにマッピングする際のクラス名を記述.
<class name="SimpleMessage"
この子要素に二つの属性id,messageについての記述を行っている.
- id
- キーは要素idで記述する. 子要素にgeneratorがある. これによっていちいち設定しなくても,idが自動採番される. 属性nameが指定されると,id値をマッピングするJavクラスのgetterで取得できる. 属性nameが指定されないと,id値はSession#getIdentifier()でないと取得できない.
- message
- キーではないので,要素propertyで指定する. 属性nameの値はマッピングするJavaクラスのsetterとgetterに使用する. 子要素のcolumnはDBテーブル上の属性の名前である.
HibernateにDBとJavaオブジェクトのマッピングをまかせるための準備ができたので,後は使用するだけである.
サンプルでは以下を行っている.
- オブジェクトを生成してHibernateを使用してそれを格納.
- 格納したオブジェクトのいくつかを読み込み.
- 読み込んだオブジェクトの属性を更新,DBへ反映.
- 格納したオブジェクトのいくつかを読み込み.
- 読み込んだオブジェクトをDBから削除.
- 全レコードを削除.
- hibernate.cfg.xmlの読み込み
- hibernate.cfg.xmlには要素session-factoryがあり,これを使用してDBへのSessionを生成してくれるSessionFactoryオブジェクトを生成する.
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();hibernate.cfg.xmlにはマッピング設定ファイルが記述されたりしているので,それらも裏で読み込まれる. 注意点はSessionFactoryオブジェクトは1つのhibernate.cfg.xmlに対して一つとなるようにする点である. 複数のDBへの接続を可能とするために,SessionFactoryにはSingletonパターンが適用されていないので,ユーザが注意してコーディングする必要がある. - トランザクション
- SessionFacotryオブジェクトからSessionオブジェクトを取得し,Sessionオブジェクトに対してトランザクションの開始を指定する.
このときTransactionオブジェクトを取得できる.
Session session = sessionFactory.openSession(); Transaction transaction= session.beginTransaction();
トランザクション終了時にはTransactionオブジェクトに対してcommitを発行する. 失敗した場合はrollback()もある. Sessionのクローズも忘れずに行う.transaction.commit(); session.close();
- オブジェクトのDBへの格納
- SessionオブジェクトにO/Rマッピングの設定があるオブジェクトと渡すSQLが発行され,O/Rマッピングに基づいてDBにデータが格納される.
SimpleMessage simpleMessage = new SimpleMessage(); simpleMessage.setMessage("hello" + i); // DBに格納 session.save(simpleMessage); - オブジェクトをDBから復元
- O/Rマッピングに基づいて,DBのデータからオブジェクトを復元(生成)するには,HQL(Hibernate Query Languqge)あるいはSQLを使用してレコードを特定するための条件を記述する.
サンプルではHQLを使用した.
Query query = session.createQuery("from SimpleMessage as msg where msg.id / 3 = ?"); query.setInteger(0, 10); List result = query.list();上のサンプルではJDBCでいうpreparestatemantのようなことをして,次に値を設定し,最後のquery.list()によってSQLが発行している. - DBレコードの更新
- JavaアプリケーションにてO/Rマッピングしているオブジェクトのメンバを更新した場合,Session#update(Object)によって更新できる.
- DBレコードの削除
- Session#delete(Object)によって削除できる.
- 任意のクエリの発行
- 上記ではJavaアプリケーション側でO/Rマッピングしているオブジェクトを取得している,あるいは取得する場合の処理だった.
手もとにそういったオブジェクトがない(あるいは必要ない)場合の処理も可能である.
例えば全レコードを削除する場合,Hibernate呼び出しにO/Rマッピングしているオブジェクトは必要なく,返却値にもそれはない.
Query query = session.createQuery("delete from SimpleMessage"); int result = query.executeUpdate(); logger.info("all delete result = " + result);Session#createQuery(String)にて任意のHQLを指定し,JDBCOと同様,executeUpdate()にてSQLを発行している.

