ORMモドキ作成 (1)
本日は仕事からのネタです(・∀・)
今日はなぜか仕事でO/Rマッパーもどきを作っていました。
処理としては単純なもので、DTOクラスからSQL文を自動生成して、テーブル単位のRCUD基本パターンを行うというもの。
ちなみに対象とするデータベースはOracle 10gでODP.NETを利用しています。
こういうのは別に自前で作成する必要は無くて、既存のフレームワークを使えばいいじゃんという話もありますが(;´Д`)
個人的にはS2Dao.NETを試してみたかったり、JavaではiBATISばかりを使っているので、iBATIS.NETはどうだろうと思ってみたりしますけど(・∀・)
後、今回はODP.NETなわけですが、Enterprise Libralyも3.0ではODP.NETをサポートするとか。
http://blogs.msdn.com/tomholl/archive/2006/06/21/641840.aspx
Enterprise LibralyももっとCoCになってくれたりすると使う気が増すんですが(´ω`)
で、既存のフレームワークとかがあるのになぜ自前でライブラリを作るのか?
例えばお客さん的にそういったものの使用を嫌がるというケースもありますが、開発メンバーのフレームワークへの学習コストとか、その案件で必要な処理を考えたときに、高機能で無くても良いから簡単かつ手軽に使える軽量フレームワークが欲しいというケースがあるからですねね。
何日もかけて既存のフレームワークを検証して癖を把握したり、開発にあたってはフレームワーク用の設定ファイルをチマチマ書くよりも、手軽に使えて中身を完全に把握している軽量ライブラリの方が使い勝手が良い場合があるからです。
まあ、日頃から既存のフレームワークに慣れていればそれで良いんですけどネ(´ω`)
で、今日作ったのは、こんな感じのDAOクラスです(・∀・)
public class GenericDao { OracleDataReader GetDtoReader(Type type, string option, params OracleParameter[] parameters); OracleDataReader GetDtoReader(Type type); ArrayList GetDtoList(Type type, string option, params OracleParameter[] parameters); ArrayList GetDtoList(Type type); object GetDto(object dto); int CountDto(Type type, string option, params OracleParameter[] parameters); int CountDto(Type type); int InsertDto(object dto); int UpdateDto(object dto); int DeleteDto(object dto); }
例えばこんな感じのテーブルがあったとして。
CREATE TABLE HOGE ( HOGE_ID NUMBER(8) NOT NULL, HOGE_DATA NVARCHAR2(10) NOT NULL PRIMARY KEY(HOGE_ID) )
それに対して、こんなDTOクラスを用意します。
public class HogeDTO { private int hogeId; private string hogeData; private object ignoreMember; [PrimaryKey] public int HogeId { get { return( this.hogeId ); } set { this.hogeId = value; } } public string HogeData { get { return( this.hogeData ); } set { this.hogeData = value; } } [IgnoreField] public object IgnoreMember { get { return( this.ignoreMember ); } set { this.ignoreMember = value; } } public HogeDTO() { } }
GenericDaoは、このDTOクラスのクラス名・プロパティ名をリフレクションで取得して、RCUD用のSQLを生成(&キャッシング)、そのSQL文を使ってデータベースへの処理を行うという単純なものです。
ポイントを挙げるとしたら、DTOクラスの銘々規則をデータベースに合わせれば、設定ファイルとか面倒なものはいらないという点でしょうか(`・ω・´)
ちなみに、プロパティ名HogeId←→フィールド名HOGE_IDの変換みたいな部分については、Strategyっぽくしてマッチングルールを交換可能にしています(`・ω・´)
PrimaryKeyAttribute、IgnoreFieldAttributeはフレームワーク側で用意しているAttributeです。
PrimaryKeyAttributeは指定されたプロパティをベースにSELECT、UPDATE、DELETE用のWHERE句を作成するためのものです。
IgnoreFieldAttributeは、そのプロパティはパーシステント対象外であることをマークします。
こんなショボイものでも、マスタ系とか単純なデータ操作で済む部分については事足りますし、それなりに便利に使えるものです。
今までの蓄積があるとはいえ1日で作ることも出来たわけだし、まあ、それなりなんじゃないかと。
ちなみに、「DataSetじゃ駄目なの?」だとか、DataSet vs PONOな話については今回は省略なのです(´ω`)