S2Dao.NET を使ってみる
開発環境はこんな感じ
- VS2005 Team Edition for Software Developers(C#)
- SqlServer 2005 Developer
- S2Container.NET 1.2.2
- S2Dao.NET 0.4.5
ソース一式をここに置いておく。
DB作成
使用するDBはこんな感じ
CREATE DATABASE [s2daotest] GO use [s2daotest] GO CREATE TABLE [dbo].[EMP] ( [EMPNO] numeric (10, 0) NOT NULL , [ENAME] nvarchar (50) NOT NULL , [DEPTNUM] numeric (10, 0) , CONSTRAINT [PK_EMP] PRIMARY KEY CLUSTERED ([EMPNO])) GO
エンティティの作成
ファイル名は「Emp.cs」で、ほとんど S2Dao.NET に含まれるサンプル(Employee)と同じ。違うのはこれくらいかな。
- DEPTNUM に NULL を許可するために System.Data.SqlTypes.SqlDecimal を使用
- Table属性を省略するためにクラス名を Emp に変更
using System; using System.Collections.Generic; using System.Text; using System.Data.SqlTypes; namespace S2DaoTestApp { public class Emp { private int _empno; public int EmpNo { get { return _empno; } set { _empno = value; } } private string _ename; public string Ename { get { return _ename; } set { _ename = value; } } private SqlDecimal _deptNum; public SqlDecimal DeptNum { get { return _deptNum; } set { _deptNum = value; } } } }
Dao インターフェイスの作成
ファイル名は「IEmpDao.cs」で、EMP テーブルのデータを全件取得するメソッドを定義する。
using System; using System.Collections.Generic; using System.Text; using Seasar.Dao.Attrs; namespace S2DaoTestApp { [Bean(typeof(Emp))] public interface IEmpDao { Emp[] GetAllList(); } }
Ex.dicon ファイル
サンプルからコピーしてきて、プロパティのビルドアクションを「埋め込まれたリソース」にしただけ。ただし、ここを参考に接続文字列を app.config から取得するように変更している。
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components namespace="Ex"> <!-- データプロバイダ --> <component name="SqlClient" class="Seasar.Extension.ADO.DataProvider"> <property name="ConnectionType">"System.Data.SqlClient.SqlConnection"</property> <property name="CommandType">"System.Data.SqlClient.SqlCommand"</property> <property name="ParameterType">"System.Data.SqlClient.SqlParameter"</property> <property name="DataAdapterType">"System.Data.SqlClient.SqlDataAdapter"</property> </component> <!-- データソース --> <component name="SqlDataSource" class="Seasar.Extension.Tx.Impl.TxDataSource"> <property name="DataProvider">Ex.SqlClient</property> <property name="ConnectionString">appSettings['ConnectionString']</property> </component> <!-- S2Dao.NETのDaoInterceptorとそれに必要なコンポーネント --> <component class="Seasar.Extension.ADO.Impl.BasicDataReaderFactory" /> <component class="Seasar.Extension.ADO.Impl.BasicCommandFactory" /> <component class="Seasar.Dao.Impl.DaoMetaDataFactoryImpl" /> <component name="DaoInterceptor" class="Seasar.Dao.Interceptors.S2DaoInterceptor"/> <!-- ローカルトランザクション用のインターセプター --> <component name="LocalRequiredTx" class="Seasar.Extension.Tx.TransactionInterceptor"> <arg><component class="Seasar.Extension.Tx.Impl.LocalRequiredTxHandler" /></arg> <property name="TransactionStateHandler">TransactionContext</property> </component> <!-- ローカルトランザクション用のインターセプターで使用します --> <component name="TransactionContext" class="Seasar.Extension.Tx.Impl.TransactionContext"> <property name="IsolationLevel">System.Data.IsolationLevel.ReadCommitted</property> </component> <!-- MSDTC(分散トランザクション)用のインターセプター --> <component name="RequiredTx" class="Seasar.Extension.Tx.TransactionInterceptor"> <arg><component class="Seasar.Extension.Tx.Impl.DTCRequiredTxHandler" /></arg> <property name="TransactionStateHandler">DTCTransactionStateHandler</property> </component> <!-- MSDTC用のインターセプターで使用します --> <component name="DTCTransactionStateHandler" class="Seasar.Extension.Tx.Impl.DTCTransactionStateHandler" /> </components>
app.dicon ファイル
app.dicon ファイルはこんな感じ。これもビルドアクションを「埋め込まれたリソース」にしておく。C#の場合、リソースを埋め込むとデフォルトの名前空間が追加されるので、Ex.dicon をインクルードする場合は「S2DaoTestApp.Ex.dicon」というように指定しないといけない。
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE components PUBLIC "-//SEASAR2.1//DTD S2Container//EN" "http://www.seasar.org/dtd/components21.dtd"> <components> <include path="S2DaoTestApp.Ex.dicon" /> <component class="S2DaoTestApp.IEmpDao"> <aspect>Ex.DaoInterceptor</aspect> </component> </components>
アプリケーション構成ファイル
app.config はこんな感じ。
Ex.dicon の時と同じように、configPath は「S2DaoTestApp.app.dicon」とする。
エンティティやDaoを見つけるために、assemblys で S2DaoTestApp を忘れずに参照しておくこと。
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="seasar" type="Seasar.Framework.Xml.S2SectionHandler, Seasar" /> </configSections> <appSettings> <add key="ConnectionString" value="Server=(local);database=s2daotest;Integrated Security=SSPI" /> </appSettings> <seasar> <configPath>S2DaoTestApp.app.dicon</configPath> <assemblys> <assembly>Seasar.Dao</assembly> <assembly>S2DaoTestApp</assembly> </assemblys> </seasar> </configuration>
動作確認
Form1 に Button と DataGridView を追加して、Button がクリックされたら DataGridView に Emp テーブルの内容が表示されるようにしてみた。
DataGridView にはデータソースとして、Emp クラスを選択しておく。
Form1 のコードはこんな感じ。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using Seasar.Framework.Container; using Seasar.Framework.Container.Factory; namespace S2DaoTestApp { public partial class Form1 : Form { public Form1() { InitializeComponent(); SingletonS2ContainerFactory.Init(); } private void button1_Click(object sender, EventArgs e) { try { button1.Enabled = false; IS2Container c = SingletonS2ContainerFactory.Container; IEmpDao dao = (IEmpDao)c.GetComponent(typeof(IEmpDao)); empBindingSource.DataSource = dao.GetAllList(); } finally { button1.Enabled = true; } } } }
最終的なソリューションの構成はこんな感じになった。
適当に EMP テーブルにデータを追加しておくとこんな感じに表示される。
SQLや ADO.NET のコードをまったく書いてないのに、ここまで出来るってやばいですな。
DataSet では扱えない、NULLを許可するフィールドも使えるし。