8.NHibernate編
これまで、主にRDBMSを対象にしたDBアクセスについて解説を行いましたが、NHibernateはRDBMSではありません。NHibernateはオブジェクト関係(O/R)マッピングフレームワークと言われるもので、言い換えれば、NHibernateを経由したDBアクセスについて解説を行う、ということになります。
Wikipediaでは、オブジェクト関係マッピングについて
データベースとオブジェクト指向プログラミング言語の間の非互換なデータを変換するプログラミング技法である。と解説しています。もう少し簡単に言うとしたら、RDBへのアクセスをあたかもdb4oのようなODBへのアクセスのように行う方法、でしょうか。
NHibernateではマッピング先のRDB上のテーブルへのデータ登録を次の様なコードで実現しています。
- Configuration cfg = new Configuration();
- cfg.Configure();
- ISessionFactory factory = cfg.BuildSessionFactory();
- ISession session = factory.OpenSession();
- Product product = new Product{ Id = 1, Name = "Clamp", Price = 12.48M, Description = "Workbench clamp" };
- session.Save(product);
- var result = session.Get<Product>(1);
NHibernateは複数のRDBMSをサポートし、これまでの記事で使用したすべてのRDBMSで使用可能です。本稿では、NHibernateを使用した、RDBMSへのDBアクセスについて解説を行います。NHibernateについてはWikipediaなどを参照して下さい。
セットアップ
NHibernateの動作に必要なアセンブリの導入を行います。各RDBMSのセットアップについては、これまでの記事を参照して下さい。ただ、本稿での動作環境は、以前と異なる部分があるので、セットアップ上の変更点については、「おまけ」の節で解説します。アセンブリの導入
NHibernateはSourceForgeのNHibernateプロジェクトページからダウンロード可能です。現時点(2009.09.02)の最新版は2.1.0.GAです(NHibernate 2.1.0はHibernate 3.2.6に相当)。「NHibernate-2.1.0.GA-bin.zip」を任意のディレクトリで展開し、次のアセンブリをGACへインストールまたは環境変数MONO_PATHに設定されているディレクトリへコピーします。
[必要なアセンブリ]
アセンブリ | 概要 |
---|---|
NHibernate.dll | NHibernate Service Provider |
Iesi.Collections.dll | required from NHibernate |
log4net.dll | required from NHibernate |
NHibernate.ByteCode.LinFu.dl | need for proxyfactory.factory_class |
LinFu.DynamicProxy.dll | need for proxyfactory.factory_class |
[導入例(MONO_PATH)]
$ echo $MONO_PATH
/home/sta/lib
$ unzip NHibernate-2.1.0.GA-bin.zip -d NHibernate-2.1.0.GA-bin/
$ cd NHibernate-2.1.0.GA-bin/Required_Bins
$ cp *.dll ~/lib
$ cd ../Required_For_LazyLoading/LinFu
$ cp *.dll ~/lib
/home/sta/lib
$ unzip NHibernate-2.1.0.GA-bin.zip -d NHibernate-2.1.0.GA-bin/
$ cd NHibernate-2.1.0.GA-bin/Required_Bins
$ cp *.dll ~/lib
$ cd ../Required_For_LazyLoading/LinFu
$ cp *.dll ~/lib
コンフィグファイル
RDBMSへの接続情報等を設定します。「NHibernate-2.1.0.GA-bin.zip」には、各RDBMS用NHibernateコンフィグファイルのテンプレートが含まれています(「展開先/Configuration_Templates」配下)。それらを参考にして、各RDBMS用のコンフィグファイルを用意します(以下は、SQLiteを対象にした設定例になります)。作業する上でのディレクトリ構造は、下表の通りとします。
ディレクトリ | ファイル |
---|---|
~/src/cs/NHibernateExample/Driver | MonoDataSqliteDriver.cs |
~/src/cs/NHibernateExample/Test | SQLite.cfg.xml |
[NHibernateコンフィグファイル例(SQLite.cfg.xml:SQLite用)]
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
- <session-factory name="NHibernateExample">
- <property name="connection.driver_class">NHibernateExample.Driver.MonoDataSqliteDriver, NHibernateExample</property>
- <property name="connection.connection_string">Data Source=/home/sta/data/sqlite/TestData.db</property>
- <property name="show_sql">false</property>
- <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
- <property name="query.substitutions">true=1;false=0</property>
- <property name="proxyfactory.factory_class">NHibernate.ByteCode.LinFu.ProxyFactoryFactory, NHibernate.ByteCode.LinFu</property>
- <mapping file="Product.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
- Configuration cfg = new Configuration();
- cfg.Configure();
- cfg.Configure("SQLite.cfg.xml");
SQLite用コンフィグファイルのテンプレートでは、SQLite用データプロバイダを使用するためのドライバとして、「NHibernate.Driver.SQLiteDriver」が設定されていますが、同ドライバで呼び出しているのは「SQLite.NET」であり、Monoで標準提供されている「Mono.Data.Sqlite」ではありません。ということで、次のような「Mono.Data.Sqlite」用のドライバを用意する必要があります。
[Mono.Data.Sqlite用ドライバ(MonoDataSqliteDriver.cs)]
- using System;
- using NHibernate.Driver;
- namespace NHibernateExample.Driver
- {
- public class MonoDataSqliteDriver : ReflectionBasedDriver
- {
- public MonoDataSqliteDriver() : base(
- "Mono.Data.Sqlite",
- "Mono.Data.Sqlite.SqliteConnection",
- "Mono.Data.Sqlite.SqliteCommand")
- {
- }
- public override bool UseNamedPrefixInSql
- {
- get { return true; }
- }
- public override bool UseNamedPrefixInParameter
- {
- get { return true; }
- }
- public override string NamedPrefix
- {
- get { return "@"; }
- }
- public override bool SupportsMultipleOpenReaders
- {
- get { return false; }
- }
- }
- }
- <?xml version="1.0" encoding="utf-8" ?>
- <configuration>
- <runtime>
- <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
- <qualifyAssembly partialName="Mono.Data.Sqlite"
- fullName="Mono.Data.Sqlite, version=2.0.0.0, publicKeyToken=0738eb9f132ed756, culture=neutral" />
- </assemblyBinding>
- </runtime>
- </configuration>
$ cd ~/lib
$ ln -s /opt/mono/2.4/lib/mono/2.0/Mono.Data.Sqlite.dll .
$ ln -s /opt/mono/2.4/lib/mono/2.0/Mono.Data.Sqlite.dll .
マッピング
次のようなProductsテーブルに関連付けられる、Productクラス、NHibernateマッピングファイルを用意します。ディレクトリ | ファイル |
---|---|
~/src/cs/NHibernateExample | Product.cs |
~/src/cs/NHibernateExample/Test | Product.hbm.xml |
[Productsテーブル]
- create table Products(
- ProductID int not null primary key,
- ProductName text not null,
- Price numeric null,
- ProductDescription text null);
[Productクラス(Product.cs)]
- namespace NHibernateExample
- {
- public class Product
- {
- int _id;
- string _name;
- decimal? _price;
- string _description;
- public virtual int Id
- {
- get { return _id; }
- set { _id = value; }
- }
- public virtual string Name
- {
- get { return _name; }
- set { _name = value; }
- }
- public virtual decimal? Price
- {
- get { return _price; }
- set { _price = value; }
- }
- public virtual string Description
- {
- get { return _description; }
- set { _description = value; }
- }
- public override string ToString()
- {
- return "ID:" + _id + " NAME:" + _name + " PRICE:" + _price + " DESCRIPTION:" + _description;
- }
- }
- }
[NHibernateマッピングファイル(Product.hbm.xml)]
- <?xml version="1.0" encoding="utf-8" ?>
- <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
- assembly="NHibernateExample"
- namespace="NHibernateExample">
- <class name="Product" table="Products">
- <id name="Id" column="ProductID">
- <generator class="assigned" />
- </id>
- <property name="Name" column="ProductName" not-null="true" />
- <property name="Price" column="Price" />
- <property name="Description" column="ProductDescription" />
- </class>
- </hibernate-mapping>
- <mapping file="Product.hbm.xml" />
$ gmcs -t:library -r:NHibernate.dll -out:./Test/NHibernateExample.dll Product.cs -recurse:./Driver/*.cs
Monoで他のDBも使ってみたよ!+(db4o、NHibernate編)5 へ続く。
0 件のコメント:
コメントを投稿