.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. ‹ # ›
© Copyright 2025 ExpyDoc