ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた

18,954 views

Published on

2013/10/12 .NET 勉強会 / ヒーロー島
『ヒーロー島 秋の収穫祭 2013』の同名のセッションの資料です

サンプルソースやフォローアップなどはこちら: http://d.hatena.ne.jp/kiyokura/20131014/p1

Published in: Technology
0 Comments
30 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
18,954
On SlideShare
0
From Embeds
0
Number of Embeds
4,621
Actions
Shares
0
Downloads
48
Comments
0
Likes
30
Embeds 0
No embeds

No notes for slide

ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた

  1. 1. ADO.NETとORMとMicro-ORM -dapper dot netを使ってみた- at ヒーロー島 秋の収穫祭 2013 2013/10/12 きよくらならみ
  2. 2. 自己紹介 • きよくら ならみ – @kiyokura / id:kiyokura • 岡山生まれ岡山育ちのプログラマー – 現在は県内の某製造業で社内SE • NET系の開発やWebアプリ開発 – Microsoft MVP for ASP.NET/IIS
  3. 3. 本セッションの目的 • Micro-ORMを知ってもらう • dapper dot netを知ってもらう
  4. 4. 本セッションのゴール • .NET向けのDBアクセス手法の概要を知る • ORMの概要と"不得手"な部分を知る • dapper dot netの概要を知る
  5. 5. 本日のアジェンダ • .NETのDBアクセステクノロジの基本 • ORM 超・概要と.NETのORM • ORM≠銀の弾丸 • Micro-ORM そしてdapper dot net • まとめ
  6. 6. .NETのDBアクセステクノロジの基本
  7. 7. 基本はADO.NET • .NETにおけるDBアクセスの基本 • 様々なデータソースに対して 『一貫性を持ったアクセス機能を実現』
  8. 8. ADO.NET ADO.NETのスタック データソース(DBほか、xmlやExcel等) データプロバイダ Connection Command DataReader Transaction Transaction DataAdapter プログラム(C# or VB.NET or etc) DataSet DataTable
  9. 9. 一貫性のある操作 • 各ソースに対応した”プロバイダ” – 製品専用のプロバイダ • SQL Server • SQL Server CE • Oracle • MySQL • PostgreSQL …等々。 – 汎用ドライバ用 • OLE DB • ODBC
  10. 10. プロバイダはインタフェースを実装 • 共通のインタフェースを実装することで 操作の一貫性を保証 – IDataReader – IDbConnection – IDbCommand – IDataParameter – IDbTransaction – IDbDataAdapter
  11. 11. 接続の基本:Connection • Connectionオブジェクトに 接続文字列をセット • 接続を開始
  12. 12. クエリ実行の基本:Command • Commandオブジェクトによりクエリ実行 – DML・DDL・DCL • CommandにSQLをセットして実行 • 結果としてレコードが返るときは? → DataReaderを使う
  13. 13. データ読込の基本:DataReader • Commandの結果DataReaderが返る • レコードに対して順番にアクセス – DBのカーソルやADOのRecordSetに近い
  14. 14. 最も基本的なデータアクセス流れ • DBに接続 – Connectionオブジェクト • コマンドにSQLをセット – Commandオブジェクト • コマンドを実行してリーダーを作成 – DataReaderオブジェクト リーダーをループしながらデータを読む
  15. 15. 最も基本的なデータアクセス流れ DB Connection 接続文字列 (1) Command SQL: SELECT * FROM HOGEHOGE (2) DataReader(3)
  16. 16. コード例
  17. 17. ここまでのまとめ .NETのDBアクセスの基本はADO.NET ソース毎に異なるプロバイダを利用 共通のインタフェースにより ソースが変わっても一貫した操作を提供 データ読み込みの基本手順 Connectionで接続 Commandで実行 DataReaderで読込
  18. 18. ORM 超・概要と.NETのORM
  19. 19. ORMって? • Object-Relational mapper / mapping – O/RM 、 O/R-M、OR-M – 「おーあーるまっぱー」 • 永続化データに対するギャップを埋める – メモリ上の変数とDB上のカラムのマッピング – "オブジェクト操作"と"DBの操作" • その他、DB操作をラップ
  20. 20. 代表的な機能 • クエリの自動生成 • データ(値)のマッピング • DB操作のラッピング • ソースコード自動生成 ライブラリや実装よって有無はあります
  21. 21. 例:Entity Framework • .NET用のORMであるEntity Framework を例としてデモします – ASP.NET MVC 4 + Entity Framework
  22. 22. Entity Frameworkの例 • メソッドを呼ぶだけでデータを取得 – 列挙型のオブジェクトとしてデータが 「マネージドのオブジェクト」として取得できる • オブジェクトに値とセットしてメソッドを呼 べば更新完了 SQLを全く意識しない DBの接続等の制御用もまったく意識しない
  23. 23. .NETで利用できるORMの例 • マイクロソフト製 – ADO.NET DataSet – LINQ to SQL – Entity Framework • サードパーティー製 – NHibernate – S2Dao.NET – LightSpeed(商用) …等々
  24. 24. ここまでのまとめ ORMはDB操作をラップ SQL作成や実行、データのオブジェクトへの マップ等 .NET向けにも多数の実装あり
  25. 25. ORM≠銀の弾丸
  26. 26. ORMを使うべきか否か • "便利なケース"では使うべき – どんどん使いましょう • "美味しくない場合"は使わなくてよい – 無理して使うようなものでもない
  27. 27. ただし当然ですが • 銀の弾丸は無い • あらゆるケースで全く問題が無いわけで は無い "美味しくない"例をいくつか考えてみます
  28. 28. DB設計がORM適さなくなりがちなケース • データがアプリケーション内に閉じない – データが多数のアプリで横断的に利用される – アプリから見えない業務ロジックが存在 • 『データ > アプリ』 – 利用範囲の他、権限や寿命 • データ中心アプローチ(DOA)
  29. 29. 基幹業務システムの例 販売データ 労務データ 製造データ 研究開発 データ 顧客データ 販売管理システム 生産管理システム 賞与計算システム 製造品質管理 システム
  30. 30. パフォーマンスで問題が出るケース • ORMでパフォーマンスが出ない場合が – 仮に設計に問題がなくても • パフォーマンス比較の例 手法 実行時間(短=速) Hand coded(DataReaderでループ) 47ms NHibernate SQL 104ms Linq 2 SQL ExecuteQuery 181ms Entity framework ExecuteStoreQuery 631ms dapper dot net の公式サイト上のベンチマーク結果より ( https://code.google.com/p/dapper-dot-net/ )
  31. 31. その他のアリがちな話 • そもそもDB設計がイケてない – 自動生成のクエリではパフォーマンスが( – 適切にリレーションが貼られていない • プロバイダが(使いたい)ORMに未対応 – たまにある • DBサーバ・ネイティブクライアント・プロバイダのそれぞ れのバージョンの対応とかも関連 • 自動生成されたSQLがDBAの怒りに触れる( – DBA:「そんなトン○キなクエリ投げるな!」
  32. 32. ここまでのまとめ ORMのメリットが生きる場合は使うべき ORMのメリットが生きない・使いにくい 場面は存在する そんなときは無理して使う必要はない
  33. 33. Micro-ORM そしてdapper dot net
  34. 34. ORMが使えなくても • なるべく楽はしたい • 生ADO.NETはいろいろ面倒 – Connectionはまだしも – SQL組み立てて – Commandを作って – Parameterを作って – 実行して – 値をオブジェクトにマッピング
  35. 35. そこでMicro-ORM • 隙間を埋めてくれるソリューション
  36. 36. Micro-ORMとは • 特徴 – フルスタックのORMほどの機能は無いが – そこそこ便利な機能があって – 軽量で – 早い • そういうカテゴリ(?)のライブラリの総称
  37. 37. 機能のあるやなしや クエリの 自動生成 データ (値)の マッピング DB操作の ラッピング ソース コード自 動生成 ☆物によってはある程度するものも
  38. 38. つまり • SQLは自分で書く必要がある • 実行時の面倒なことのうち、 ある程度のことをやってくれる
  39. 39. 代表例 • dappar dot net – この後、少し詳しく話します • Massive – https://github.com/robconery/massive • PetaPoco – http://www.toptensoftware.com/petapoco
  40. 40. dapper dot net • Dapper.NETとも書かれる – .NET向けのMicro-ORM • オープンソース – ApachとMITのデュアルライセンス • サイトはこの辺 – https://code.google.com/p/dapper-dot-net – https://github.com/SamSaffron/dapper-dot- net
  41. 41. dapper dot net • 作った人: Sam Saffron – Stack Overflowの中の人 • 早い – 生SQL実行(DataReader)とほぼ互角 – Stack Overflowのパフォーマンス改善のため に作られた(らしい)
  42. 42. dapper dot net • どのDBで使える? – ADO.NET準拠のプロバイダが使えるなら大抵 いけるんでは? • IDbConnectionの実装なら、多分 • 確認した範囲 – SQL Server / SQL Server CE – Oracle – MySQL – postgreSQL
  43. 43. 使い方 • 2STEPで簡単!
  44. 44. STEP1 • NuGetで一発導入!
  45. 45. STEP2 • 使いたい場面でDapper名前空間をイン ポート – 拡張メソッドなのでインポート必須!
  46. 46. これだけです
  47. 47. 実際の例をご紹介します • ADO.NETで直接実行する場合との 対比で紹介します
  48. 48. 例1:とりあえずループして読みだす
  49. 49. ADO.NETの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var sql = "select ID, Name , Age , Email From Employee;"; var cmd = new SqlCeCommand(sql, cn); using (var dr = cmd.ExecuteReader()) { while (dr.Read()) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", dr["ID"], dr["Name"], dr["Age"], dr["Email"]); } } }
  50. 50. dapperの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var sql = "select ID, Name , Age , Email From Employee;"; var result = cn.Query(sql); foreach (var d in result) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", d.ID, d.Name, d.Age, d.Email); } }
  51. 51. ポイント1 • Query拡張メソッド – Connectionオブジェクトを拡張
  52. 52. ポイント2 • 戻り値はIEnumerable<dynamic>
  53. 53. つまり • Query拡張メソッドを実行すると • 戻り値はIEnumerable<dynamic>が返っ てくる • dynamicの中身はカラム名から自動生成さ れた匿名型にマップされている
  54. 54. 例2:用意した型にマップする
  55. 55. ADO.NETの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var cmd = new SqlCeCommand("select ID, Name , Age , Email From Employee;", cn); var result = new List<EmployeeEntity>(); using (var dr = cmd.ExecuteReader()) { while (dr.Read()) { result.Add(new EmployeeEntity() { ID = (int)dr["ID"], Name = (string)dr["Name"], Age = (int)dr["Age"], Email = (string)dr["Email"] }); } } foreach (var d in result) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", d.ID, d.Name, d.Age, d.Email); } }
  56. 56. dapperの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var sql = "select ID, Name , Age , Email From Employee;"; var result = cn.Query<EmployeeEntity>(sql); foreach (var d in result) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", d.ID, d.Name, d.Age, d.Email); } }
  57. 57. ポイント1 • Query<T>拡張メソッド – マップしたい型を型パラメータに指定
  58. 58. ポイント2 • 戻り値はIEnumerable<dynamic>
  59. 59. つまり • 型パラメータTをとる Query拡張メソッドを実行すると • 戻り値はIEnumerable<T>が返ってくる – クエリの結果が型Tにマップされている • カラム名に対応したメンバにマップ • 適切に型の変換も行われている
  60. 60. 例3:パラメータをバインドする
  61. 61. ADO.NETの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var cmd = new SqlCeCommand("select ID, Name , Age , Email From Employee where Age = @age;", cn); var param = cmd.CreateParameter(); param.SqlDbType = System.Data.SqlDbType.Int; param.Direction = System.Data.ParameterDirection.Input; param.ParameterName = "age"; param.Value = 25; cmd.Parameters.Add(param); var result = new List<EmployeeEntity>(); using (var dr = cmd.ExecuteReader()) { while (dr.Read()) { result.Add(new EmployeeEntity() { ID = (int)dr["ID"], Name = (string)dr["Name"], Age = (int)dr["Age"], Email = (string)dr["Email"] }); } } foreach (var d in result) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", d.ID, d.Name, d.Age, d.Email); }
  62. 62. dapperの場合 using (var cn = new SqlCeConnection(connectionString)) { cn.Open(); var sql = "select ID, Name , Age , Email From Employee where Age = @Age;"; var result = cn.Query<EmployeeEntity>(sql, new { Age = 25 }); foreach (var d in result) { Console.WriteLine("ID:{0} , Name:{1} , Age:{2} , Email:{3}", d.ID, d.Name, d.Age, d.Email); } }
  63. 63. ポイント • Query<T>拡張メソッドの第二引数に パラメータを指定 – SQL文のパラメータと同じメンバがあればOK • 匿名型でもOK
  64. 64. つまり • Query拡張メソッドの第二引数に • SQL文中のパラメータと 同名のメンバを持つオブジェクト を渡すと • パラメータとしてバインドして実行する
  65. 65. その他 • 複数の型(ネストされた型)にバインド することも可能 – 但し、基本1:1 • もちろん、INSERT / UPDATE / DELETE 等も発行できる
  66. 66. FAQ
  67. 67. Q1:速度は? • A1:早いです – 生ADO.NETとほぼ誤差の範囲くらい – 公式サイトのベンチマークも参照
  68. 68. Q2: DB側の命名がsnake_case… • A2-1:SQLで別名を付ける – first_name as FirstName • A2-2:SetTypeMapという仕組みを使う – 詳細は公式サンプルや、neue ccさんのblog エントリを参照 • http://neue.cc/2012/12/11_390.html
  69. 69. Q3:SQL書けません! • A3:頑張って書いてください – どうしても解らない人は、クエリビルダ的な ツール使うといいのでは • SQL Server Management Studio • A5:SQL Mk-2 • SI Object Browser – もしくは、ヘルパライブラリを使う手も • Dapper.Rainbow • Dapper.Contrib
  70. 70. Q4:マップするクラスは自分書く? • A4:自分で書きましょう – 別途、自動化・半自動化はできるのでは • DDLやDB定義書から • マクロやT4で自動生成等
  71. 71. 補足情報 • ソースは1ファイルなのでGithubからとっ てきて入れてもいいです – ちょっと改変して使いたいならそれが楽 • MySQLで高負荷かけると不具合が出るら しい – 詳細と対策などはneue ccさんのblogエント リ参照: • http://neue.cc/2013/08/06_423.html
  72. 72. ここまでのまとめ 生ADO.NETとORMの間を埋める、 Micro-ORM dapper dot netは早くて手軽で便利
  73. 73. まとめ
  74. 74. まとめ(1) • .NETのデータアクセスはADO.NETが基本 • ORMは便利だが使いにくいケースもある • 間を埋める選択してのMicro-ORM
  75. 75. まとめ(2) • Micro-ORMは大体こんなもの – SQLは自力で書く – 実行結果やパラメータをマップしてくれる • dapper dot net – 多分もっともメジャーなMicro-ORM – 手軽で便利、(割と)かゆいところに手が届く
  76. 76. 最後に • 「ORMが適用しにくい」と思ったら無理 に適用しなくていいです – 無理に使っても余計な苦労を背負い込む事が 多い気がします
  77. 77. 最後に • 生ADO.NETよりも 「もう少し文化的にやりたい」 とき、dapperはお勧めのソリューション だと思います • Web Pages(WeMatrix)にも良いかも – WebMatrix.Dataに物足りなくなったときの 次の一手として
  78. 78. 参考
  79. 79. dapper公式関連 • 公式サイト – https://code.google.com/p/dapper-dot-net/ • ベンチマーク結果あり • ソースコード – https://github.com/SamSaffron/dapper-dot- net • テストコード(サンプルとしても有用)あり – https://github.com/SamSaffron/dapper-dot- net/blob/master/Tests/Tests.cs • Test内に、ベンチマークのプログラムもあり
  80. 80. その他 • Micro ORMs with Sam Saffron and Rob Conery – http://www.infoq.com/articles/ORM- Saffron-Conery – MassiveのRob ConeryとdapperのSam SaffronへのMicro-ORMについてのインタ ビュー記事

×