成長したいIT技術検証所

2004/12/14 (火) NHibernate

[]NHibernate

 Javaでは有名なO/RマッピングフレームワークHibernate。その.NET版であるNHibernateがα版にて公開中であることを知りました。

 常識的に考えたらα版なんて商用ソフトには恐くて使えませんが、とある旧システムにあるデータを新システムコンバートする機能に適用したいと考えています。

 動作検証して、5時間以上もはまってようやく動かすことができました。疲れた・・・。

 A Quick Start Guide to NHibernateを参考にしています。


Index

動作環境

サンプルの使用

NHibernateのダウンロード

usersテーブルの作成

VS.NETプロジェクトの作成

Userクラスの作成

O/Rマッピングファイルの作成

データベース設定の作成

実行クラスの作成


動作環境

WindowsXP

Microsoft SQL Server 2000

Visual Studio .NET 2003

言語C#です。


サンプルの仕様

 DBにあるusersテーブルにレコードを1件追加します。


NHibernateのダウンロード

 NHibernateのファイルページからダウンロードします。今回は、Alpha-0.5.0.0を使用しています。

 ダウンロードしたら適当フォルダ解凍します。


usersテーブルの作成

 usersテーブルを以下のSQL文で作成します。

CREATE TABLE users (
  LogonID nvarchar(20) NOT NULL default '0',
  Name nvarchar(40) default NULL,
  Password nvarchar(20) default NULL,
  EmailAddress nvarchar(40) default NULL,
  LastLogon datetime default NULL,
  PRIMARY KEY  (LogonID)
)

VS.NETプロジェクトの作成

1)NHibernateSampleという名前でプロジェクトを新規作成します。

2)プロジェクトアプリケーション構成ファイル(App.config)を追加します。

3)参照設定に

  [NHibernate解凍フォルダ]/bin/NHibernate.dll

  [NHibernate解凍フォルダ]/bin/log4net.dll

 を追加します。


Userクラスの作成

 Userクラスを作成します。

User.cs

using System;

namespace NHibernate.Sample.QuickStart
{
	public class User
	{
		private string id;
		private string userName;
		private string password;
		private string emailAddress;
		private DateTime lastLogon;


		public User()
		{
		}

		public string Id 
		{
			get { return id; }
			set { id = value; }
		}

		public string UserName 
		{
			get { return userName; }
			set { userName = value; }
		}

		public string Password 
		{
			get { return password; }
			set { password = value; }
		}

		public string EmailAddress 
		{
			get { return emailAddress; }
			set { emailAddress = value; }
		}

		public DateTime LastLogon 
		{
			get { return lastLogon; }
			set { lastLogon = value; }
		}
		
	}
}

O/Rマッピングファイルの作成

 マッピングファイルを作成します。

User.hbm.xml

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

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.0">

	<class name="NHibernate.Sample.QuickStart.User, NHibernateDemo" table="users">
		<id name="Id" column="LogonId" type="String" length="20"> 
			<generator class="assigned" /> 
		</id> 
		<property name="UserName" column= "Name" type="String" length="40"/> 
		<property name="Password" type="String" length="20"/> 
		<property name="EmailAddress" type="String" length="40"/>
		<property name="LastLogon" type="DateTime"/>
	</class>

</hibernate-mapping>


 User.hbm.xml作成後に、User.hbm.xmlのプロパティを開き「ビルドアクション」を「埋め込まれたリソース」に設定します。.hbm.xmlファイルは全てこうして埋め込みをしないとNHibernateは動作しません。

 なお.hbm.xmlファイルの命名方法は「クラス名.hbm.xml」です。名前空間は不要です。


データベース設定の作成

 App.configの<configuration>に以下を追加します。

	<configSections>
		<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
		<section name="nhibernate" type="System.Configuration.NameValueSectionHandler, System, Version=1.0.3300.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="Persist Security Info=True;User ID=sa;Password=パスワード;Initial Catalog=データベース名;Data Source=データベースインスタンス" />
		
	</nhibernate>

	<log4net>
		<!-- コンソール出力用 -->
		<appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
			<layout type="log4net.Layout.PatternLayout">
				<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
			</layout>
		</appender>
		<!-- ログファイル出力用 -->
		<appender name="LogFileAppender" type="log4net.Appender.FileAppender">
			<param name="File" value="Sample.log" />
			<param name="AppendToFile" value="true" />
			<layout type="log4net.Layout.PatternLayout">
				<param name="Header" value="[Header]\r\n" />
				<param name="Footer" value="[Footer]\r\n" />
				<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
			</layout>
		</appender>
		<!-- ログファイル出力用(日付またはファイルのサイズ制約に基づいた多数のログを生成) -->
		<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
			<param name="File" value="SampleRolling.log" />
			<param name="AppendToFile" value="true" />
			<param name="MaxSizeRollBackups" value="10" />
			<param name="MaximumFileSize" value="100KB" />
			<param name="RollingStyle" value="Size" />
			<param name="StaticLogFileName" value="true" />
			<layout type="log4net.Layout.PatternLayout">
				<param name="Header" value="[Header]\r\n" />
				<param name="Footer" value="[Footer]\r\n" />
				<param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
			</layout>
		</appender>
		
		<!-- Setup the root category, add the appenders and set the default level -->
		<root>
			<level value="WARN" />
			<appender-ref ref="LogFileAppender" />
			<appender-ref ref="ConsoleAppender" />
		</root>
		
		<!-- Specify the level for some specific categories -->
		<logger name="Sample.LoggingExample">
			<level value="ALL" />
			<appender-ref ref="RollingLogFileAppender" />
		</logger>
	</log4net>

実行クラスの作成

 以下のクラスを作成します。

QuickStartMain.cs

using System;
using log4net;
using NHibernate.Cfg;

namespace NHibernate.Sample.QuickStart
{
	class QuickStartMain
	{
		private static readonly ILog log = LogManager.GetLogger(typeof(QuickStartMain));

		[STAThread]
		public static void Main(string[] args)
		{
			try
			{
				Configuration cfg = new Configuration();
				cfg.AddAssembly("NHibernateDemo");

				ISessionFactory factory = cfg.BuildSessionFactory();
				ISession session = factory.OpenSession();
				ITransaction transaction = session.BeginTransaction();
				User newUser = new User();
				newUser.Id = "user1";
				newUser.UserName = "user1_name";
				newUser.Password = "user1_pass";
				newUser.EmailAddress = "user1@nhibernate.sample.com";
				newUser.LastLogon = DateTime.Now;

				session.Save(newUser);

				transaction.Commit();
				session.Close();
			}
			catch (ADOException e)
			{
				log.Debug(e.Message);
			}

			Console.WriteLine("追加完了");
			Console.ReadLine();
		}
	}
}

 これで実行すれば、usersテーブルにレコードが1件追加されます。


参考:

NHibernate