対決! O/Rマッパー vs. オブジェクト指向DB

第2回 HibernateとCaché、Javaとの好相性はどっちだ

ネクストデザイン
村山 徹
2006/1/13
オブジェクト指向プログラミングとリレーショナル・データベースの相性の悪さは、アプリケーション開発者の悩みの種だ。これを回避する2つの方法、すなわちO/Rマッピングツールとオブジェクト指向データベースを取り上げ、Javaの永続化方式を比較するのが本連載の狙いである。(編集部)

はじめに

主な内容
--Page 1--
はじめに
Hibernateを使ったJavaオブジェクトの永続化
  ステップ1 ドメインモデルを作成する
  ステップ2 永続クラスとマッピング情報を作成する
--Page 2--
  ステップ3 テーブルを作成する
  ステップ4 アプリケーションコードを書く
  ステップ5 実行する
--Page 3--
Cachéを使ったJavaオブジェクトの永続化
  ステップ1 ドメインモデルを作成する
  ステップ2 永続クラスを定義する
  ステップ3 テーブルを作成する
  ステップ4 アプリケーションコードを書く
  ステップ5 実行する

 前回「Javaのオブジェクト永続化に何を選ぶ?」では、永続化の意味や、永続化が多くのアプリケーション・システムにとって共通の問題であり、解決方法も1通りではないことを述べました。今回は、O/Rマッピングツールの「Hibernate」と、オブジェクト指向データベースとしての「Caché」、それぞれの使用方法を具体的に紹介し、その使い方の違いや類似点を確認してみたいと思います。

Hibernateを使ったJavaオブジェクトの永続化

 まず、Hibernateを使って永続化する方法を見てみましょう。Hibernateはいろいろな使用状況が想定されていて、それぞれの状況に合った使い方ができるようになっています。例えば、「すでに運用中のRDBMSが存在していて、そのデータを使用しなければならない」や、「テーブルは自分で設計したい」(図1 使用例B)といった状況が考えられています。

 本稿で想定する状況は、新規のシステム開発です。そして、テーブル設計は行いません。永続ストレージにはRDBMSを使用し、設計したオブジェクト・モデルをできるだけシンプルに、テーブルなどを意識せずに永続化したい、という状況を想定します(図1 使用例A)。

 なお、今回使用したHibernateのバージョンは2.1.6(本稿執筆時点の最新バージョンは3.1 beta2)、RDBMSは「Firebird 1.5.1」です。

 図1 Hibernateの想定する使用例

ステップ1 ドメインモデルを作成する

 本事例注1ではドメイン・オブジェクトとして、「アクター」「ユースケース」「シナリオ」といった名前のオブジェクトが登場します。しかし、ここでは問題を簡素化するために、最初は1つのクラス「CaObject」の永続化だけを考えることにしましょう。同様に、永続化したい状態もString型の属性「name」ただ1つとします。CaObjectは、「ユースケース」や「シナリオ」のスーパークラスとして、本事例の中で導入したクラスです(図2)。

注1: 筆者が本稿を執筆するもととなった開発事例「ユースケース記述を作成するためのツール」のこと。詳細は第1回「Javaのオブジェクト永続化に何を選ぶ?」を参照。

図2 ドメインモデルの一部

ステップ2 永続クラスとマッピング情報を作成する

 CaObjectを永続化するための定義情報として、2つのXMLファイルと「CaObject.java」を作成します。各ファイルの目的は次のとおりです。

ファイル名 目的
hibernate.cfg.xml
(リスト1)
RDBMSへの接続情報と、マッピングファイル名(CaObject.hbm.xml)を指定する
CaObject.hbm.xml
(リスト2)
永続クラスのマッピングファイル。永続化するクラスの名前、属性名や型などを指定する。Hibernateは、このマッピング情報を基にテーブル名や列名、型などを決定する
CaObject.java
(リスト3)
永続クラスのJavaソースコード。ここには、デフォルトコンストラクタと、各永続フィールドのsetter/getterメソッドを記述する必要がある。この例では、Hibernateを使ううえで必要最小限のコードだけを書いている
表1 Hibernateで必要となる定義情報

 各ファイルの目的から、その内容もおおよそ理解できると思います。ただ、1つ注目してほしい点があります。「id」という属性(リスト2、リスト3)です。この属性は、図2のクラス図にはありません。これは、テーブル(CaObjectテーブル)の主キーとしてHibernateが必要とする属性です。もしも、リスト2、リスト3に存在しない場合には、Hibernateによって自動的に追加されます注2

注2:もともとオブジェクト指向の世界では、インスタンスを一意に特定するための識別子は、実行環境やオブジェクト指向データベースによって暗黙的に提供されます。アプリケーション側では、必須の属性ではありません。例えば「ユースケース」や「アクター」などは、主キーに相当する属性を持ちませんが、各インスタンスは正しく識別されます。インスタンスを特定する識別子は、インスタンスの生成時に自動的に割り当てられるのです。つまり、ここに追加した「id」は、RDBMSを使うために必要な属性なのです。もちろん、ユーザーから識別できるようにユースケースIDやアクターIDなどを導入したモデルも多いと思います。

<?xml version="1.0" ?>
<!DOCTYPE hibernate-configuration PUBLIC 
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd" >
<hibernate-configuration>
<session-factory>
    <!--Firebird JDBC Driver connection -->
    <property name="connection.driver_class">
      org.firebirdsql.jdbc.FBDriver
    </property>
    <property name="connection.url">
      jdbc:firebirdsql://localhost/C:/compass.fdb
    </property>
    <property name="connection.username">sysdba</property>
    <property name="connection.password">masterkey</property>
    <property name="dialect">
      net.sf.hibernate.dialect.FirebirdDialect
    </property>
    <property name="show_sql">false</property>
    <property name="use_outer_join">true</property>
    <!-- Mapping files -->
    <mapping resource="CaObject.hbm.xml"/>
</session-factory>
</hibernate-configuration>
リスト1 hibernate.cfg.xml

<?xml version="1.0" encoding="Shift_JIS"?> 
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD//EN" 
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping> 
    <class name="CaObject" > 
        <id name="id" column="id" type="java.lang.Long"> 
            <generator class="sequence"/> 
        </id> 
        <property name="name" type="java.lang.String"/> 
    </class> 
</hibernate-mapping>
リスト2 CaObject.hbm.xml

public class CaObject  {
    private Long id;
    private String name;
    public CaObject() {
    }
    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return this.name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
リスト3 CaObject.java

  1/3

 Index
対決! O/Rマッパー vs. オブジェクト指向DB(2)
HibernateとCaché、Javaとの好相性はどっちだ
Page 1
・はじめに
・Hibernateを使ったJavaオブジェクトの永続化
  ステップ1 ドメインモデルを作成する
  ステップ2 永続クラスとマッピング情報を作成する
  Page 2
  ステップ3 テーブルを作成する
  ステップ4 アプリケーションコードを書く
  ステップ5 実行する
  Page 3
・Cachéを使ったJavaオブジェクトの永続化
  ステップ1 ドメインモデルを作成する
  ステップ2 永続クラスを定義する
  ステップ3 テーブルを作成する
  ステップ4 アプリケーションコードを書く
  ステップ5 実行する


対決! O/Rマッパー vs. オブジェクト指向DB


Database Expert フォーラム 新着記事
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Database Expert 記事ランキング

本日月間