ではいよいよHibernateによるデータベースアクセスプログラムを実装し、動作させてみます。初めにデータ検索用のサンプルプログラムを作成します。「src」ディレクトリに次のFindSample.javaを作成してください。
import entity.Emp; import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.cfg.Configuration; public class FindSample { public static void main(String[] args) throws HibernateException { Configuration config = new Configuration(); config = config.configure(); // 設定の読み込み // セッションファクトリーの作成 SessionFactory sessionfactory = config.buildSessionFactory(); // セッションオープン Session session = sessionfactory.openSession(); // Empテーブルの全件検索 List list = session.createCriteria(Emp.class).list(); for (int i = 0; i < list.size(); i++) { // レコードとなるEmpオブジェクトを取得 Emp emp = (Emp)list.get(i); // EMPNOとENAME列のデータを表示 System.out.println(emp.getEmpno() + ":" + emp.getEname()); } } }
プログラムを実行すると、以下のような出力情報がコンソールに表示されます。
Hibernateを使ってレコードを検索する方法はいくつかありますが、ここではnet.sf.hibernate.SessionインターフェイスのcreateCriteria()メソッドを使用しています。このメソッドの引数に対象テーブルの永続化クラスを指定することでnet.sf.hibernate.Criteriaオブジェクトを取得することができます。Criteriaオブジェクトはテーブルに対するクエリ用オブジェクトであり、このサンプルのような単純な全件検索のほかにExpressionオブジェクトを利用した条件検索も可能です。
Criteriaオブジェクトからはlist()メソッドを使って、レコードをListオブジェクトとして取得します。whileループの中で1件ずつEmpオブジェクトにキャストしながらgetterメソッドを呼び出してデータを取得しています。
続いてEMPテーブルに対する更新を行ってみましょう。「src」ディレクトリに以下の「UpdateSample.java」を作成してください。
import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.Transaction; import net.sf.hibernate.cfg.Configuration; public class UpdateSample { public static void main(String[] args) throws HibernateException { Configuration config = new Configuration(); config = config.configure(); SessionFactory sessionfactory = config.buildSessionFactory(); Session session = sessionfactory.openSession(); // トランザクションの開始 Transaction trans = session.beginTransaction(); // EMPNO「1」を持つEmpオブジェクトを取得 Emp emp = (Emp)session.load(Emp.class, new Integer(1)); // JOBを「Sales」に変更 emp.setJob("Sales"); session.update(emp); // UPDATE実行 trans.commit(); // コミット session.close(); // クローズ } }
このプログラムではEMPNOが「1」であるレコードのJOBを「Sales」に更新するプログラムです。更新前のレコードは以下のようになっています。
ここでUpdateSampleを実行してください。実行後JOBの値が「Architect」から「Sales」に変更されていることを確認できます。
データベースの更新処理ではトランザクション制御が必要になってきますが、HibernateではSessionオブジェクトのbeginTransaction()メソッドによって取得するnet.sf.hibernate.Transactionオブジェクトを使用してトランザクション制御を行います。
このプログラムで使用しているSessionオブジェクトのload()メソッドは、1件のレコードを主キーによって取り出す際に使用します。load()メソッドによって取得したEmpオブジェクトのsetterメソッドを使って更新する値を指定し、Sessionオブジェクトのupdate()メソッドを呼び出せば更新終了です。トランザクションをコミットすることを忘れないでください。
データを更新して永続化(データベースへの保存)するには通常SQLのUPDATE文を記述しますが、Hibernateを使用すればオブジェクトのプロパティを変更するだけの手軽さで更新処理が実行できることが体験できたと思います。
続いてデータ挿入のサンプルプログラムです。UpdateSample.javaと同様に、「src」ディレクトリにInsertSampleというクラスを作成しましょう。
import net.sf.hibernate.HibernateException; import net.sf.hibernate.Session; import net.sf.hibernate.SessionFactory; import net.sf.hibernate.Transaction; import net.sf.hibernate.cfg.Configuration; public class InsertSample { public static void main(String[] args) throws HibernateException{ Configuration config = new Configuration(); config = config.configure(); SessionFactory sessionfactory = config.buildSessionFactory(); Session session = sessionfactory.openSession(); Transaction trans = session.beginTransaction(); // 新しいレコードの作成 Emp emp = new Emp(); emp.setEmpno(new Integer(6)); emp.setEname("Takahashi"); session.save(emp); // 挿入実行 trans.commit(); session.close(); } }
このプログラムでは新しいEmpオブジェクトを生成し、各プロパティに対するsetterメソッドを用いてデータをセットしています。データをセットし終えた後はSessionオブジェクトのsave()メソッドを用いて永続化(データの挿入)を行っています。
プログラムを実行後、EMPテーブルを検索すると、新しいレコードが挿入されていることが確認できます。
続いて先ほど挿入したデータを削除します。次のようなDeleteSample.javaを作成してください(ほかのコードと同じ部分の記述は省略しています)。
…(中略 トランザクションの開始まではInsertSampleと同じ)… // 削除対象オブジェクトの作成 Emp emp = new Emp(); emp.setEmpno(new Integer(6)); // 主キーが「6」であるEMPオブジェクトをマーク session.delete(emp); // 削除実行 trans.commit(); session.close(
プログラムを実行後、テーブルを確認してください。先ほど挿入したデータが削除されていることが確認できますね。
今回は単純な「検索・更新・挿入・削除」の操作を行いました。O/Rマッピングフレームワークを利用することでテーブルのレコードをオブジェクトとして扱えるため、データ取得後にカラムごとの型を気にして取り出すような処理を記述する必要はありません。JDBCの記述と比較して非常にシンプルなプログラムになることが理解できたと思います。
またEntity Beanを利用したことがあれば、Hibernateが提供するO/Rマッピングの手軽さを特に実感できたのではないでしょうか。Entity BeanではEJBコンテナへのデプロイが必要ですが、Hibernateを使うとコンテナへのデプロイの必要はありません。そのためJ2EEアプリケーションサーバーを使ったWebアプリケーションのみならず、Javaを利用するアプリケーションすべてに使用することができます。またデプロイが必要ないためローカルでの単体テストが容易に実行できます。
このようにHibernateはO/Rマッピングを解決するソリューションであり、Entity Beanよりもシンプルな仕組みを持っています。次回はHibernateを実践的に使えるレベルまで解説を進めていきたいと思います。
山本 大(やまもと だい)
株式会社クロノスに勤務するITアーキテクト。甲南大学 経営学部 卒業。J2EE、.NETにこだわらずベストソリューションを提供できるマルチプラットフォームアーキテクトを目指す。『XMLマスター教科書 プロフェッショナル』(翔泳社)や雑誌などで執筆活動も行っている。
Copyright © ITmedia, Inc. All Rights Reserved.