「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-戻る
--[[モジュール構成]]
--[[データアクセス]]

*目次 [#n987a637]
#contents

*概要 [#xd0bad3f]

*詳細 [#ya27e458]

**自作Daoクラス [#p684509d]
個別にDaoクラスを使用してデータ アクセスする場合、~
インテリジェンスなD層(Dao)クラス として、機能毎に「自作Daoクラス」を実装。

***サンプル・コード [#e5b6269d]
-[[性能を考慮した動的パラメタライズド・クエリの連続実行方法>バッチ処理方式#y92d7822]]

-ストアド プロシージャの実行~
最新版では、SetParameterの拡張により、[[汎用Daoクラス>#w11892a0]]でも実行可能になった。
 /// <summary>「sp_help」ストアドプロシージャを実行する。</summary>
 /// <param name="objectName">「sp_help」ストアドプロシージャの「objname」パラメタに指定する文字列</param>
 /// <param name="ds">「sp_help」ストアドプロシージャが返す結果セット(複数返る)</param>
 /// <returns>「sp_help」ストアドプロシージャの戻り値(成功:「」、失敗:「」)</returns>
 public int sp_help(string objectName, out DataSet ds)
 {
   // ストアドプロシージャを指定する。
   this.SetSqlByCommand("sp_help", CommandType.StoredProcedure); // CommandTypeにStoredProcedureを設定
 
   // 引数パラメタを設定する。
   this.SetParameter("objname", objectName);
 
   // 戻り値パラメタを設定する。
   // 戻り値用のパラメタを指定する場合、Parameter.Directionプロパティに、ParameterDirection.ReturnValueを指定する。
   // アウトプット パラメタを指定する場合も、同様に、Parameter.Directionプロパティに、ParameterDirection.Outputを指定する。
   this.SetParameter("ret", null, null, -1, ParameterDirection.ReturnValue);
 
   // ストアドプロシージャを実行し、データリーダを戻す。
   // ストアド プロシージャの実行には、this.ExecSelect_DR()メソッドを使用する。
   SqlDataReader drd = (SqlDataReader)this.ExecSelect_DR();
 
   // 結果セットを取得する
   ds = new DataSet();
 
   // 結果セットは複数取得可能
   // ループなどを使用して複数の結果セットを取得できる。
   // DataTable.Load()メソッドでは、結果セットが自動的に次に送られる。
   // DataTable.Load()メソッドを使用しない場合、DataReader.NextResult()メソッドを使用して、次に読む結果セットに進む。
   do
   {
     // DataTableを生成
     DataTable dt = new DataTable();
 
     // データリーダから結果をロード
     dt.Load(drd);
 
     // DataTableを格納
     ds.Tables.Add(dt);
 
   } while (!drd.IsClosed);
 
   // データリーダを閉じる。
   drd.Close();
 
   // ストアドプロシージャの戻り値パラメタの値を取得。
   return (int)this.GetDam.GetParameter("ret").Value;
 }

**汎用Daoクラス(CmnDao) [#f357a5ed]
汎用的なDaoクラスを使用して主に参照系のデータアクセス処理を実行する。

***サンプル・コード [#w11892a0]
-最も簡単なデータアクセス例
 // 汎用Daoで参照系SQLを実行
 CmnDao cmnDao = new CmnDao(this.GetDam());
 
 // 動的SQLを指定
 cmnDao.SQLFileName = "ShipperSelect.xml";
 
 // パラメタ ライズド クエリのパラメタに対して、動的に値を設定する。
 cmnDao.SetParameter("P1", testParameter.ShipperID);
 
 // 戻り値 dt
 DataTable dt = new DataTable();
 
 // 汎用Daoを実行
 cmnDao.ExecSelectFill_DT(dt);

-パラメタライズド・クエリを使用した条件検索 + あいまい検索処理~
動的SQLには、動的パラメタライズド・クエリが有効である。~
条件検索 + あいまい検索という複雑なSQLであっても、~
以下のようなSQL定義(XML)とプログラムで容易に対応が可能である。

--SQL定義
 <?xml version="1.0" encoding="shift_jis" ?>
 <ROOT>
   SELECT
     A, B, C
     FROM T
     WHERE
       <IF>AND A = @A</IF>
       <IF name="A_LIKE">AND A LIKE @LIKE_A</IF>
       <IF>AND B = @B</IF>
       <IF name="B_LIKE">AND B LIKE @LIKE_B</IF>
       <IF>AND C = @C</IF>
     ORDER BY <IF name="SEQUENCE">A<ELSE>B</ELSE></IF>
 </ROOT>

--コード
 ' ファイルから読み込む
 Me.SetSqlByFile2("XXX.xml")
 
 ' パラメタ設定
 
 ' パラメータA
 If PV.A <> "" Then
   If PV.A_IsAimai Then
     ' LIKE前方一致検索
     Me.SetParameter("LIKE_A", PV.A & "%")
   Else
     ' 通常の=一致検索
     Me.SetParameter("A", PV.A)
   End If
 End If
 
 ' パラメータB
 If PV.B <> "" Then
   If PV.B_IsAimai Then
     ' LIKE前方一致検索
     Me.SetParameter("LIKE_B", PV.B & "%")
   Else
     ' 通常の=一致検索
     Me.SetParameter("B", PV.B)
   End If
 End If
 
 ' パラメータC
 Me.SetParameter("C", PV.C)
 
 ' 並び順
 Me.SetParameter("SEQUENCE ", PV.SEQ)
 
 ' 結果セットの取得
 RV.dt = New DataTable()
 Me.ExecSelectFill_DT(RV.dt)
※ LIKE句で使用する、「 % 」や「 _ 」などのワイルドカードを~
文字列中で使用する場合は、これも別途エスケープする必要がある。

-ストアドプロシージャの利用例
--その1
 // 汎用Daoでストアドを実行
 CmnDao cmnDaoSP = new CmnDao(this.GetDam());
 
 // ストアドを指定
 cmnDaoSP.SQLText = "sp_help";
 
 // パラメタを指定する(入力、出力)。
 cmnDaoSP.SetParameter("objname", "Shippers");
 cmnDaoSP.SetParameter("ret", null, null, -1, ParameterDirection.ReturnValue);
 
 // 汎用Daoを実行
 SqlDataReader drd = (SqlDataReader)cmnDaoSP.ExecSelect_DR();
 
 // 結果セットを取得する
 DataSet ds = new DataSet();
 
 // 結果セットは複数取得可能
 do {
   // DataTableを生成
   DataTable dt = new DataTable();
 
   // データリーダから結果をロード
   dt.Load(drd);
 
   // DataTableを格納
   ds.Tables.Add(dt);
 
 } while (!drd.IsClosed);
 
 // データリーダを閉じる。
 drd.Close();
 
 // 戻り値を取得
 int i = (int)cmnDaoSP.GetParameter("ret");

--その2
---Open棟梁の汎用Daoを使用したストアド実行サンプル~
https://gist.github.com/daisukenishino2/a97e2017a0c683d2c858e39741b63949

**自動生成Daoクラス [#t389966a]
自動生成したDaoクラスを使用してデータ アクセスする場合、
-[[D層自動生成ツール]]を使用すれば、テーブル単位のCRUD部品を自動生成可能。
-更新系処理は、この「自動生成Daoクラス」を使用してデータ アクセスする。

***サンプル・コード [#vcc99a63]

-参照~
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Samples/2CS_sample/GenDaoAndBatUpd_sample/Business/LayerB_BatUpd.cs#L143
 // 戻り値クラスを生成
 TestReturnValue testReturn = new TestReturnValue();
 
 // ↓業務処理-----------------------------------------------------
 
 // データアクセス クラスを生成する
 DaoProducts daoProducts = new DaoProducts(this.GetDam());
 
 // 全件取得
 DataTable dt = new DataTable();
 daoProducts.D2_Select(dt);
 
 // 戻り値を戻す
 testReturn.dt = dt;
 
-(バッチ)更新~
https://github.com/OpenTouryoProject/OpenTouryo/blob/develop/root/programs/CS/Samples/2CS_sample/GenDaoAndBatUpd_sample/Business/LayerB_BatUpd.cs#L34
 // 戻り値クラスを生成
 TestReturnValue testReturn = new TestReturnValue();
 
 // ↓業務処理-----------------------------------------------------
 
 // データアクセス クラスを生成する
 DaoProducts daoProducts = new DaoProducts(this.GetDam());
 
 // ROW毎に処理
 foreach (DataRow dr in testParameter.dt.Rows)
 {
   // パラメタをクリアする。
   daoProducts.ClearParametersFromHt();
 
   switch (dr.RowState)
   {
     case DataRowState.Added:
 
       #region 1件挿入
 
       // 設定(インサート値)
       daoProducts.PK_ProductID = dr["ProductID"].ToString();
       daoProducts.ProductName = dr["ProductName"].ToString();
       daoProducts.SupplierID = dr["SupplierID"].ToString();
       daoProducts.CategoryID = dr["CategoryID"].ToString();
       daoProducts.QuantityPerUnit = dr["QuantityPerUnit"].ToString();
       daoProducts.UnitPrice = dr["UnitPrice"].ToString();
       daoProducts.UnitsInStock = dr["UnitsInStock"].ToString();
       daoProducts.UnitsOnOrder = dr["UnitsOnOrder"].ToString();
       daoProducts.ReorderLevel = dr["ReorderLevel"].ToString();
       daoProducts.Discontinued = dr["Discontinued"].ToString();
 
       // インサート(S1でよい)
       testReturn.obj = daoProducts.S1_Insert();
 
       #endregion
 
       break;
 
     case DataRowState.Deleted:
 
       #region 1件削除
 
       // 設定(主キー)
       daoProducts.PK_ProductID = dr["ProductID", DataRowVersion.Original].ToString();
       // ★ 楽観排他をする場合は、ここにタイムスタンプを追加する。
 
       // デリート(タイムスタンプを指定する場合は、D4_Delete)
       testReturn.obj = daoProducts.D4_Delete();
 
       #endregion
 
       break;
 
     case DataRowState.Modified:
 
       #region 1件更新
 
       // 設定(主キー)
       daoProducts.PK_ProductID = dr["ProductID"].ToString();
 
       // ★ 楽観排他をする場合は、ここにタイムスタンプを追加する。
       // ↓は、DataRowVersion.Originalを使用した楽観排他の例
       daoProducts.ProductName = dr["ProductName", DataRowVersion.Original].ToString();
       daoProducts.SupplierID = dr["SupplierID", DataRowVersion.Original].ToString();
       daoProducts.CategoryID = dr["CategoryID", DataRowVersion.Original].ToString();
       daoProducts.QuantityPerUnit = dr["QuantityPerUnit", DataRowVersion.Original].ToString();
       daoProducts.UnitPrice = dr["UnitPrice", DataRowVersion.Original].ToString();
       daoProducts.UnitsInStock = dr["UnitsInStock", DataRowVersion.Original].ToString();
       daoProducts.UnitsOnOrder = dr["UnitsOnOrder", DataRowVersion.Original].ToString();
       daoProducts.ReorderLevel = dr["ReorderLevel", DataRowVersion.Original].ToString();
       daoProducts.Discontinued = dr["Discontinued", DataRowVersion.Original].ToString();
 
       // 更新値設定
       daoProducts.Set_ProductName_forUPD = dr["ProductName"].ToString();
       daoProducts.Set_SupplierID_forUPD = dr["SupplierID"].ToString();
       daoProducts.Set_CategoryID_forUPD = dr["CategoryID"].ToString();
       daoProducts.Set_QuantityPerUnit_forUPD = dr["QuantityPerUnit"].ToString();
       daoProducts.Set_UnitPrice_forUPD = dr["UnitPrice"].ToString();
       daoProducts.Set_UnitsInStock_forUPD = dr["UnitsInStock"].ToString();
       daoProducts.Set_UnitsOnOrder_forUPD = dr["UnitsOnOrder"].ToString();
       daoProducts.Set_ReorderLevel_forUPD = dr["ReorderLevel"].ToString();
       daoProducts.Set_Discontinued_forUPD = dr["Discontinued"].ToString();
 
       // アップデート(タイムスタンプを指定する場合は、D3_Update)
       testReturn.obj = daoProducts.D3_Update();
 
       #endregion
 
       break;
 
     default:
       break;
     }
 }

**Dao集約クラス [#ra46728e]
汎用的なDaoクラス、自動生成したDaoクラスを集約する場合、

-B層から「汎用Daoクラス」、「自動生成Daoクラス」を集約して使用することも可能。
-このクラスを「Dao集約クラス」と呼ぶ。
 /// <summary>Dao集約クラスのベースクラスの例</summary>
 public class BaseConsolidateDao {
   /// <summary>データアクセス制御クラス</summary>
   private BaseDam _dam;
 
   /// <summary>データアクセス制御クラス</summary>
   protected BaseDam Dam {
     get { return this._dam; }
   }
 
   /// <summary>コンストラクタ</summary>
   /// <param name="dam">データアクセス制御クラス</param>
   public BaseConsolidateDao(BaseDam dam) {
     this._dam = dam;
   }
 }

*メソッド [#sa6028f2]
以下のメソッドを使用してデータアクセスを行う。

**SQL設定処理 [#d201de8d]
-SetSqlByFileメソッド
-SetSqlByCommandメソッド

**コネクション & トランザクション管理 [#ma366933]
-ConnectionOpenメソッド
-ConnectionCloseメソッド
-BeginTransactionメソッド
-CommitTransactionメソッド
-RollbackTransactionメソッド

**SQLパラメタ設定処理 [#d67f7231]
-SetUserParameterメソッド
-SetParameterメソッド
-GetParameterメソッド
-ClearParametersメソッド

**クエリの実行 [#hae319c9]
-ExecSelectScalarメソッド
-ExecSelectFill_DTメソッド
-ExecSelectFill_DSメソッド
-ExecSelect_DRメソッド
-ExecInsUpDel_NonQueryメソッド



トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS