miniN3

.NETでもS2Dao
~S2Dao.NET~
2006.5.14
Seasar.NET
杉本 和也
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
自己紹介
• 高知県の株式会社アイビスというところに勤務
しています
• 2005/4/29にSeasar Sandboxプロジェクトに
S2.NETが承認され、以来Seasarで活動して
います
• S2Dao.NETは2005/9/27にSandbox.NETの
プロジェクトとして承認され開発をしております
• 現在はSeasar.NETのリーダもさせて頂いてお
ります
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
現在のSeasar.NETの状況
• S2Container.NET 1.2.0
– Seasar.NETプロジェクト
• S2Dao.NET 0.4.1
– Sandbox.NETプロジェクト
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NETとは
• JavaのS2Daoを.NET(C#)に移植しました
– コミッタは青木さん、金野さん、太田さん、藤井さん、
杉本の5人
• マッピング情報をXMLに記述しないO/Rマッピ
ングフレームワーク
– ADO.NETの知識が不要
– SQLを自動生成
– SQLを外部ファイルに用意することもできる
• なにより簡単で、すぐに使い方を覚えることが
できます
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
一般的なデータベース取得(C#)
C#の場合
using(SqlConnection cn = new SqlConnection(“接続文字列"))
{
cn.Open();
using(SqlCommand cmd = new SqlCommand(“SQL文", cn))
{
cmd.Parameters.Add(new SqlParameter("@deptnum", deptnum));
using(SqlDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
{
Employee emp = new Employee();
emp.Empno = Convert.ToInt32(reader["empno"]);
・・・データをセット(省略)
employees.Add(emp);
}
}
}
}
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
一般的なデータベース取得(VB.NET)
VB.NETの場合
Dim cn = New SqlConnection(“接続文字列"))
Try
cn.Open()
Dim cmd As New SqlCommand(“SQL文", cn)
Try
cmd.Parameters.Add(New SqlParameter("@deptnum", deptnum))
Dim reader As SqlDataReader = cmd.ExecuteReader()
Try
While reader.Read()
Dim emp As New Employee()
emp.Empno = Convert.ToInt32(reader("empno"))
・・・データをセット(省略)
employees.Add(emp)
End While
Finally
reader.Close()
End Try
Finally
cmd.Dispose()
End Try
Finally
cn.Dispose()
End Try
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
一般的な方法の問題点
• オブジェクトの生成・クローズがいっぱい
– データプロバイダのオブジェクト生成にバグが混入
する可能性
– クローズを忘れる可能性
• カラム数が多いとデータのセットが大変
– データのマッピングを間違える可能性
– データのキャストを間違える可能性
• SQLのテストが行いにくい
– SQLが変数に埋め込まれており、テストが行いにく
い
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NETを見てみる
それでは、
S2Dao.NETを見てみよう!
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
サンプルで使用するテーブル
EMP2(従業員テーブル)
カラム名
論理名
型
EMPNO
従業員番号
Numeric (4,0)
ENAME
従業員名
Varchar(10)
DEPTNUM
部署番号
Numeric (2,0)
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NETを使う為に必要な物
• diconファイル(必要なコンポーネントが登録さ
れている)
• データを格納するためのEntityクラス
• Daoインターフェース
• 必要であればSQLファイル
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Diconファイル
• S2Dao.NETに必要なコンポーネントを登録
<components namespace=“Ex”>
<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="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.ADO.Impl.DataSourceImpl">
<property name="DataProvider">Ex.SqlClient</property>
<property name=“ConnectionString”>“接続文字列"</property>
</component>
</components>
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
データを格納するためのEntityクラス
VB.NETの場合
C#の場合
<Table("EMP2")> _
Public Class Employee
Private _empno As Integer
Private _ename As String
Private _deptnum As Short
[Table("EMP2")]
public class Employee
{
private int empno;
private string ename;
private short deptnum;
Public Property Empno() As Integer
Get
Return _empno
End Get
Set
_empno = value
End Set
End Property
・・・(他のプロパティは省略)
End Class
public int Empno
{
set { empno = value; }
get { return empno; }
}
・・・(他のプロパティは省略)
}
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Daoインターフェース
Daoインターフェースにメソッドを作成していきます
例は、全ての従業員を取得するGetAllListメソッド
VB.NETの場合
<Bean(GetType(Employee))> _
Public Interface IEmployeeDao
Function GetAllList() As IList
End Interface
C#の場合
[Bean(typeof(Employee))]
public interface IEmployeeDao
{
IList GetAllList();
}
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoInterceptorの適用
• IEmployeeDaoインターフェースに
DaoInterceptorを適用します
<components>
<include path=“Ex.dicon” />
<component class=“Dao.IEmployeeDao”>
<aspect>Ex.DaoInterceptor</aspect>
</component>
</components>
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
SQLファイル
SQLを自前で用意したい場合は、同じ名前空間に
Daoのインターフェース名_メソッド名.sql
というSQLファイルを作成します。
さっきのGetAllListメソッドのSQLを
自前で用意する場合は
IEmployeeDao_GetAllList.sql
になります。
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NET詳細
• S2Dao.NETの動作は、主に下記の3点で制御
されます。
– 命名規則
– 属性によるメタデータ
– SQLコメント
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
EntityクラスのTable属性
• テーブル名とクラス名は同じにします
• もし異なる場合にはTable属性で指定します
VB.NETの場合
<Table("EMP2")> _
Public Class Employee
C#の場合
[Table("EMP2")]
public class Employee
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
EntityクラスのColumn属性
• カラム名とプロパティ名は同じにします
• もし異なる場合にはColumn属性で指定します
VB.NETの場合
<Column(“EMPNO")> _
Public Property EmployeeNo() As Integer
Get
C#の場合
[Column(“EMPNO")]
public int EmployeeNo
{
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
EntityクラスのN:1マッピング
• 部署テーブル (Department) と結合するようなN:1で
関連付けられるような場合はRelno属性(0から始ま
る結合の順番)とRelkeys属性(N側のカラム名:1側
のカラム名)を使用します。
– キーが複数ならカンマで区切ります
– N側と1側のカラム名が等しい場合は
<Relkeys(“DEPTNUM”)>のように省略できます
– さらに1側のカラムがプライマリキーの場合はRelkeys属性
を省略できます
VB.NETの場合
<Relno(0), Relkeys(“DEPTNUM:DEPTNO> _
Public Property Department() As Department
C#の場合
[Relno(0), Relkeys(“DEPTNUM:DEPTNO”)]
public Department Department
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Entityクラスのその他の属性
• ID(プライマリキー)をRDBMSで自動生成させ
るためのID属性
• 永続化されないカラムを指定する
NoPersistentProps属性
• versionNoによる排他制御用のプロパティを指
定するVersionNoProperty属性
• Timestampによる排他制御用のプロパティを
指定するTimestampProperty属性
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoインターフェースのBean属性
• DaoがどのEntityクラスに関連付けられている
かをBean属性で指定します
VB.NETの場合
<Bean(GetType(Employee)> _
Public Interface IEmployeeDao
・・・
End Interface
C#の場合
[Bean(typeof(Employee)]
public interface IEmployeeDao
{
・・・
}
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Daoインターフェースのメソッド定義
• 更新処理
– 更新処理の引数の型はEntityクラスにします
– 戻り値はvoidあるいはSystem.Int32,
System.Data.SqlTypes.SqlInt32,
NullableInt32(NHibernateContrib)を指定します
– 戻り値がvoidでない場合は更新行数が戻ります
– INSERT処理
• メソッド名をInsert, Add, Createで始めます
– UPDATE処理
• メソッド名をUpdate, Modify, Storeで始めます
– DELETE処理
• メソッド名をDelete, Removeで始めます
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Daoインターフェースのメソッド定義
• SELECT処理
– 検索処理は戻り値の型により動作が決まります
– 戻り値の型がSystem.Collections.IListであれば
Entityのリストを返します
– 戻り値の型がEntityクラスの配列なら、Entityの配
列を返します
– 戻り値の型がEntityクラスならEntityを返します
– それ以外の場合は1行1カラムの値を返すように
S2Dao.NETは想定して動作します
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
メソッド定義 - INSERT処理
VB.NETの場合
Function InsertEmployee(emp as Employee) As Integer
C#の場合
int InsertEmployee(Employee emp);
Daoの呼び出し
(C#)
実行結果
Employee emp = new Employee();
emp.Empno = 7999;
emp.Ename = "Kazuya";
emp.Deptnum = 12;
int ret = employeeDao.InsertEmployee(emp);
DEBUG 論理的なコネクションを取得しました
DEBUG INSERT INTO EMP2 (DEPTNUM, ENAME,
EMPNO) VALUES (12, 'Kazuya', 9999)
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
メソッド定義 - UPDATE処理
VB.NETの場合
Function UpdateEmployee(emp as Employee) As Integer
C#の場合
int UpdateEmployee(Employee emp);
Daoの呼び出し
(C#)
実行結果
Employee emp = new Employee();
emp.Empno = 7999;
emp.Ename = “Sugimoto";
emp.Deptnum = 12;
int ret = employeeDao.UpdateEmployee(emp);
DEBUG 論理的なコネクションを取得しました
DEBUG UPDATE EMP2 SET DEPTNUM = 12,
ENAME = 'Sugimoto' WHERE EMPNO = 7999
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
メソッド定義 - DELETE処理
VB.NETの場合
Function DeleteEmployee(emp as Employee) As Integer
C#の場合
int DeleteEmployee(Employee emp);
Daoの呼び出し
(C#)
Employee emp = new Employee();
emp.Empno = 7999;
int ret = employeeDao.DeleteEmployee(emp);
実行結果
DEBUG 論理的なコネクションを取得しました
DEBUG DELETE FROM EMP2 WHERE EMPNO =
7999
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
メソッド定義 - SELECT処理
VB.NETの場合
Function GetEmployees1() As IList
Function GetEmployees2() As Employee()
C#の場合
IList GetEmployees1();
Employee[] GetEmployees2();
Daoの呼び出し
(C#)
実行結果
Employee[] emps = employeeDao.GetEmployees();
SELECT EMP2.DEPTNUM, EMP2.ENAME,
EMP2.EMPNO FROM EMP2
DEBUG 論理的なコネクションを取得しました
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoインターフェースのQuery属性 (1)
• 自動生成するSELECT文にWHERE句や
ORDER BY句を追加します
• 従業員名の昇順で並び替えた全従業員のリス
トを取得するメソッドは下記のように書きます
C#の場合
VB.NETの場合
<Query(“order by ename asc”)> _
Function GetAllListEnameAsc() As IList
実行結果
[Query(“order by ename asc”)]
IList GetAllListEnameAsc();
SELECT EMP2.DEPTNUM, EMP2.ENAME,
EMP2.EMPNO FROM EMP2 order by ename asc
DEBUG 論理的なコネクションを取得しました
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoインターフェースのQuery属性 (2)
• バインド変数コメントを使ってメソッドの引数をSQLに
渡すこともできます
• 従業員名から従業員を取得するメソッドは下記のよう
に書きます
VB.NETの場合
<Query(“ename=/*ename*/”)> _
Function GetEmployeeByEname(ename As String) As Employee
C#の場合
実行結果
[Query(“ename=/*ename*/”)]
Employee GetEmployeeByEname(string ename);
SELECT EMP2.DEPTNUM, EMP2.ENAME,
EMP2.EMPNO FROM EMP2 WHERE ename='ALLEN‘
DEBUG 論理的なコネクションを取得しました
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoインターフェースのSql属性
• SQLをまるまる記述することができます
• 従業員名と部署番号から従業員番号を取得するメ
ソッドは下記のようになります
VB.NETの場合
<Sql(“select empno from emp2 where ename=/*ename*/’ALLEN’ and
deptnum=/*deptnum*/30”)> _
Function GetEmpnoByEnameDeptnum(ename As String, deptnum As
Short) As Integer
C#の場合
実行結果
[Sql(“select empno from emp2 where ename=/*ename*/’ALLEN’
and deptnum=/*deptnum*/30”)]
int GetEmpnoByEnameDeptnum(string ename, short deptnum);
select empno from emp2 where ename='SMITH' and deptnum=20
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
Daoインターフェースの
NoPersistentProps属性
• 更新の時にSQLに含めたくないプロパティを指定しま
す
• 更新に部署番号を含めたくない場合のメソッドは下記
のようにします
VB.NETの場合
<NoPersistentProps(“Deptnum”)> _
Function UpdateEmployeeNoDeptnum(emp As Employee) As Integer
C#の場合
[NoPersistentProps(“Deptnum”)]
int UpdateEmployeeNoDeptnum(Employee emp);
実行結果
DEBUG 論理的なコネクションを取得しました
DEBUG UPDATE EMP2 SET ENAME = 'Sugimoto' WHERE
EMPNO = 7499
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
DaoインターフェースのPersistentProps属性
• 更新の時にこのプロパティだけSQLに含めたい場合
に指定します
• 更新に部署番号だけを含めたい場合のメソッドは下
記のようにします
VB.NETの場合
<PersistentProps(“Deptnum”)> _
Function UpdateDeptnum(emp As Employee) As Integer
C#の場合
[PersistentProps(“Deptnum”)]
int UpdateDeptnum(Employee emp);
実行結果
DEBUG 論理的なコネクションを取得しました
DEBUG UPDATE EMP2 SET DEPTNUM = 99 WHERE
EMPNO = 7499
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
SQLファイル
• 従業員番号から従業員名を取得するSQLファイル(ビ
ルドアクションを「埋め込まれたリソース」にする)を実
行する場合は下記のようにします
VB.NETの場合
Function GetEnameByEmpno(empno As Integer) As String
C#の場合
string GetEnameByEmpno(int empno);
SQLファイル(IEmployeeDao_GetEnameByEmpno.sql)
select ename from emp
where empno=/*empno*/20
実行結果
select ename from emp
where empno=7499
DEBUG 論理的なコネクションを取得しました
DEBUG 論理的なコネクションを閉じました
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NET
• あとはSQLコメントでSQLを動的に変化させ
たりすることもできますが、だいたいこんな感
じです
• 本家のS2Daoのドキュメントも参考にしてみ
てください
• S2Dao.NETのドキュメントも今後、作成して
いきます
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NETのExamples
• Examplesアプリケーションの紹介
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
S2Dao.NETの今後
• Sandbox.NET卒業を目指します
• DataSetへ対応します
• .NET Framework 2.0対応版を作成します
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
まとめ
• S2Dao.NETがデータアクセス部分の生産性と、
品質を向上させます
• お手伝いしてくださる方も随時募集しています
– ソースコードを作成してくれる方
• RDBMSの対応
– ドキュメントを作成・指揮してくれる方
– Examplesを作成してくれる方
• VB.NET
• C#
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›
おわり
• ご清聴ありがとうございました
• S2Dao.NETのページ
– http://s2dao.net.sandbox.seasar.org/
• S2Container.NETのページ
– http://s2container.net.seasar.org/
• sugimotokazuyaの日記
– http://d.hatena.ne.jp/sugimotokazuya/
© Copyright the Seasar Project and the others 2005. all rights reserved.
‹
#
›