特集

ASP.NETで実践するO/Rマッピング(NHibernate編)

山田 祥寛(http://www.wings.msn.to/
2005/09/21

Page1 Page2 Page3 Page4

NHibernate

 NHibernateは、Java向けの代表的なO/Rマッピング・ツールであるHibernateの.NET Framework環境への移植版だ。

 Hibernateは、機能性、パフォーマンスともに定評のあるオープンソースのツールであり、ドキュメントが充実している、導入が容易である、などの点からO/Rマッピングを基礎から学びたいユーザーにとっても魅力的なツールである。Hibernateに関する詳細は、別稿「Hibernateで理解するO/Rマッピング」でも紹介されているので、そちらを参照していただくとよいだろう。

 一方、Hibernateの.NET版であるNHibernateは、執筆時点でバージョン0.9.1とまだ歴史は浅いものの、Java環境での実績を考慮すれば十分利用に値するツールである。現在も精力的にバージョンアップが重ねられており、近日中の1.0リリースを期待したい。

NHibernateのインストールと設定手順

 O/Rマッピング・ツールというと、とかく「設定ファイルが多い」「実際にコーディングに入るまでが大変」というイメージをお持ちの方もいるかもしれない。実際それはまったくもってそのとおりなのだが、最初にきちんと準備さえしておけば、あとはデータベースへのアクセス方法の変更があっても、ビジネス・ロジックそのものには変更を加える必要がない、という手軽さがO/Rマッピングの魅力だ。それに、そもそも設定ファイルの記述は理解さえしてしまえば定型的な作業であり、難しいことは何もない。まずは設定ファイルをきちんと押さえて、O/Rマッピングを極めよう。

[1]NHibernateの利用に必要なファイルを配置する

 NHibernateを利用するに当たっては、以下のサイトから必要なファイルをダウンロードする必要がある。本稿では、執筆時点での最新バージョンである0.9.1を例に取り上げるが、NHibernateは日々精力的に更新が行われているので、その時々の最新安定版を利用していただきたい。

 ダウンロードしたファイル(本稿の例では、nhibernate-0.9.1.0.zip)を解凍すると、いくつかのフォルダとファイルが展開されるはずだ。本稿ではASP.NETのWebアプリケーションを題材にするため、「bin」フォルダに含まれるすべての「.dll」ファイルを、Webアプリケーション・ルート直下の「bin」フォルダにコピーする。

[2]NHibernateによるデータベース接続情報を定義する

 次に、NHibernateが利用するデータベース接続情報を構成ファイル(web.config)上で宣言しておく必要がある。以下は、本稿のサンプルで利用するweb.configの記述例だ(データベース製品としてはSQL Server 2000を利用)。

<?xml version="1.0" encoding="UTF-8" ?>

<configuration>

  <configSections>
    <section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.5000.0,Culture=neutral, PublicKeyToken=b77a5c561934e089" />
  </configSections>

  <nhibernate>
    <add key="hibernate.connection.provider"
      value="NHibernate.Connection.DriverConnectionProvider" />
    <add key="hibernate.dialect"
      value="NHibernate.Dialect.MsSql2000Dialect" />
    <add key="hibernate.connection.driver_class"
      value="NHibernate.Driver.SqlClientDriver" />
    <add key="hibernate.connection.connection_string"
      value="Data Source=(local);User ID=sa;Password=sa;Persist Security Info=True;Initial Catalog=sample" />
  </nhibernate>

</configuration>
NHibernateが利用するデータベース接続情報を記述した構成ファイル(web.config)

 まず<configSections>要素は、構成ファイルに新しい構成セクションを追加定義するための要素である。NHibernateに関する設定を構成ファイル上で宣言できるようにするためには、あらかじめ<configSections>要素により、追加する構成セクション名(name属性)と構成セクションを読み込む際に使用するハンドラ・クラス(type属性)とを宣言する必要がある。この記述がない場合には、後続の<nhibernate>要素が認識されないので注意すること。

 NHibernateに関する設定を行っているのが、<nhibernate>要素だ。ここでは<add>要素により、NHibernateの動作に必要な一連のパラメータを設定する。以下に、サンプルで利用しているものも含め、<nhibernate>要素で記述可能な主要パラメータを列挙しておく。

パラメータ名 概要
hibernate.connection.provider_class 接続時に使用するプロバイダ(完全修飾名)
hibernate.connection.driver_class 接続時に使用するドライバ(完全修飾名)
hibernate.connection.connection_string データベース接続文字列
hibernate.dialect データベース依存の機能を吸収するためのDialectクラス(完全修飾名)
hibernate.prepare_sql プリペアド・ステートメントを有効にするか
hibernate.default_schema デフォルトのスキーマ名
hibernate.connection.isolation トランザクションの分離レベル(ReadCommitted、ReadUncommitted、RepeatableRead、Serializableなど)
NHibernateにおける主な動作パラメータ

 表中のDialectクラスとは、データベース製品ごとの方言を吸収するためにNHibernateが提供するユーティリティだと思っていただければよい。Dialectクラスを利用することで、開発者はデータベース製品独自の方言(仕様差)を意識することなく、データベース・アクセスを行うことができるというわけだ。

 以下に、データベース依存の設定値の例を示しておく。ここでは、NHibernateが対応する主要なデータベース製品としてSQL Server、Oracle、Accessを例に挙げているが、NHibernateではほかにもDB2、MySQL、PostgreSQL、Sybase、FireBird、SQLiteなどなど、主要なデータベース製品の利用が可能だ。

データベース パラメータ名 設定値
SQL Server hibernate.connection.driver_class NHibernate.Driver.OleDbDriver.OracleClientDriver
hibernate.connection.driver_class NHibernate.Driver.SqlClientDriver
hibernate.connection.connection_string Data Source=(local);User ID=sa;Password=sa;Initial Catalog=sample
hibernate.dialect NHibernate.Dialect.MsSql2000Dialect
Oracle hibernate.connection.driver_class NHibernate.Driver.OracleClientDriver
hibernate.connection.connection_string Data Source=Sample;User ID=scott;Password=tiger;
hibernate.dialect NHibernate.Dialect.OracleDialect
Access hibernate.connection.driver_class NHibernate.Driver.OleDbDriver
hibernate.connection.connection_string Provider=Microsoft.Jet.OLEDB.4.0;Data Source=d:\sample\sample.mdb
hibernate.dialect NHibernate.Dialect.MsAccess2000Dialect
設定パラメータのデータベースごとの記述例

[3]マッピング・ファイルを定義する

 マッピング・ファイルとは、その名のとおり、テーブル上のフィールドとクラスで定義されているプロパティとを関連付けるための定義ファイルのことである。

 ここでは、以下のような「booksテーブル」に対応する「Bookクラス」を関連付けてみることにしよう(Bookクラスについては後述する)。

フィールド名 データ型 概要
isbn VARCHAR(30) ISBNコード(主キー)
title VARCHAR(100) 書名
price INT 価格
publish VARCHAR(50) 出版社
published DATETIME 配本日
booksテーブルのフィールド・レイアウト

 マッピング・ファイルは「クラス名.hbm.xml」という命名規則に従う必要がある(ここではBookクラスにひも付けるので「Book.hbm.xml」とする)。Book.hbm.xmlの内容は、以下のとおりだ。

<?xml version="1.0" encoding="UTF-8" ?>

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">
  <class name="Com.Msn.Wings.Book, Book" table="books">
    <id name="Isbn" column="isbn">
      <generator class="assigned" />
    </id>
    <property name="Title" column="title" />
    <property name="Price" column="price" />
    <property name="Publish" column="publish" />
    <property name="Published" column="published" />
  </class>
</hibernate-mapping>
NHibernateによるマッピング・ファイル(Book.hbm.xml)

 クラスとテーブルとの関連付けを定義するのは、<class>要素の役割だ。name属性に「クラスの完全修飾名, アセンブリ名」を、table属性に対応するテーブル名を指定する。

 <class>要素の配下に含められる主な子要素は、以下のとおり。

要素名 概要
<id> 主キー・フィールドとクラスのプロパティとの関連付けを定義
<property> クラスのプロパティとテーブルのフィールドとの関連付けを定義
<one-to-one> 外部の永続化クラスへのリレーションシップを定義(1対1の関係)
<many-to-one> 外部の永続化クラスへのリレーションシップを定義(多対1の関係)
<class>要素配下に記述可能な主な子要素

 テーブル上のフィールドとクラスのプロパティとを関連付ける最も一般的な要素が<property>要素だ。name属性でプロパティ名を、column属性でフィールド名をそれぞれ指定する(プロパティ名とフィールド名とが同一である場合には、column属性は省略することも可能)。また、ここでは割愛しているが、<property>要素ではtype属性を利用することで、NHibernate上で使用するデータ型(Int32、String、Char、DateTime、Timestamp、Singleなど)を明示的に宣言することもできる。

 テーブル上の主キー・フィールドを表すのは<id>要素の役割だ。<id>要素は、主キーの生成方法を宣言するための<generator>要素を含むことができる。<generator>要素のclass属性では、以下のような値を指定可能だ。

設定値 概要
increment long/short/int型の自動連番を生成
identity IDENTIFY型を利用してlong、short、int型の識別子を生成(SQL Server、DB2、MySQL、Sybase、HypersonicSQLでのみ利用可能)
sequence SEQUENCEを利用してlong/short/int型の識別子を生成(Oracle、DB2、PostgreSQLでのみ利用可能)
hilo hi/loアルゴリズムを利用してlong/short/int型の識別子を生成
seqhilo SEQUENCEから取り出した値を基にhi/loアルゴリズムを利用してlong、short、int型の識別子を生成
uuid.hex 128bit UUIDアルゴリズムを利用してstring型の識別子(32文字の16進数表現)を生成
uuid.string 128bit UUIDアルゴリズムを利用してstring型の識別子(16文字のASCII文字列)を生成(PostgreSQLでは使用不可)
native データベース依存(identity、sequence、hiloのいずれかを選択)
assigned アプリケーション側で識別子を決定
<generator>要素のclass属性で使用可能な値

 もちろん、ここで紹介しているのはマッピング・ファイルの中でも特によく利用する要素で、そのほかにもマッピング・ファイルで指定可能な要素は多岐にわたる。マッピング・ファイル内で利用可能な要素の詳細については、NHibernateマニュアルを参照いただきたい。

 上記のマッピング・ファイルの例では<generator>要素のclass属性で「assigned」を指定しており、この場合にはプログラム中で適切なユニークIDを付与することになる。

[4]永続化クラスを定義する

 次に、テーブルと関連付けるための永続化クラスを用意しておこう。永続化クラスは、各プロパティで扱う値を保持するためのプライベートなフィールドと、それにアクセスするためのプロパティを含む単純なクラスだ。

using System;

namespace Com.Msn.Wings {
  public class Book {

    private string _isbn;
    private string _title;
    private int _price;
    private string _publish;
    private DateTime _published;

    // booksテーブルのisbnフィールドに対応するプロパティ定義
    public string Isbn {
      get {return _isbn;}
      set {_isbn=value;}
    }
    ……中略……
  }
}
Imports System

Namespace Com.Msn.Wings
  Public Class Book

    Private _isbn As String
    Private _title As String
    Private _price As Integer
    Private _publish As String
    Private _published As DateTime

    ' booksテーブルのisbnフィールドに対応するプロパティ定義
    Public Property Isbn As String
      Get
        Return _isbn
      End Get
      Set
        _isbn=Value
      End Set
    End Property
    ……中略……
  End Class
End Namespace
booksテーブルと関連付ける永続化クラスであるBookクラスの定義
(上:C#版「Book.cs」、下:VB.NET版「Book.vb」)

 ここで、クラスが永続化クラスであるための条件は、以下の3点だ。

  • デフォルト・コンストラクタを持つこと

  • プライベートなフィールドに対応するプロパティを持つこと

  • 主キーを持つ場合には、これを保持するプライベートなフィールドと対応するプロパティを持つこと

 デフォルト・コンストラクタとは、引数を持たないコンストラクタのことをいう。インスタンス化するときの初期化処理として特別な処理を必要としない場合には、本稿のサンプルのように省略しても構わない。

 Book.cs/Book.vbを作成したら、コマンドラインからコンパイルを行っておく必要がある。この際、手順[3]で作成したマッピング・ファイルをあわせてアセンブリに組み込む必要がある。マッピング・ファイルのようなリソースを組み込むためには、csc.exe/vbc.exeコマンドで/resオプションを指定し、組み込みたいリソースを指定するだけだ。

> csc /target:library /res:Book.hbm.xml Book.cs
> vbc /target:library /res:Book.hbm.xml Book.vb
マッピング・ファイルを指定した永続化クラスのコンパイル方法
(上:C#の場合、下:VB.NETの場合)

 コンパイルに成功した場合C#、VB.NETいずれにおいても、Book.dllが生成されるはずなので、これをアプリケーション・ルート配下の「bin」フォルダにコピーしておく。


 INDEX
  [特集] ASP.NETで実践するO/Rマッピング(NHibernate編)
    1..NETの向けのO/Rマッピング・ツール
  2.NHibernateのインストールと設定手順
    3.NHibernate経由でデータベースを検索する
    4.NHibernateによるデータ登録
 


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間