1. 程式人生 > >Dapper擴展SQL跟蹤及全局緩存通知

Dapper擴展SQL跟蹤及全局緩存通知

images and names 執行時間 參數 ndt ted 提示 trac

具體原因就不說了,目前項目的構成有兩部分,一部分是是基於框架開發的,另一部是由於早期業務是采用自定義開發模式,雖然數據訪問層都是基於Dapper,

但要做全局sql跟蹤及緩存通知,調整代碼還是有些麻煩,最後還是動手簡單擴展一個Dapper的源碼,從底層來進行處理。

調整Dapper源碼中有一個很重要的類:CommandDefinition.cs

1、執行SQL前攔截事件

技術分享

2、執行SQL後攔截事件(後失敗會不觸發)

技術分享

3、SQLMapper.cs增加一行代碼(此處應該是作者漏掉了,沒有細讀)

技術分享

4、附上SqlMapperTrace.cs源碼

  1 using System;
  2
using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Dapper 8 { 9 /// <summary> 10 /// Sql執行攔截事件 11 /// </summary> 12 /// <param name="traceInfo"></param> 13 public delegate void BeforeCommandExecute(TraceInfo traceInfo);
14 /// <summary> 15 /// SQL運行成功後攔截事件 16 /// </summary> 17 /// <param name="traceInfo"></param> 18 public delegate void AfterCommandExecute(TraceInfo traceInfo); 19 /// <summary> 20 /// DapperSQL執行跟蹤 21 /// </summary> 22 public class SqlMapperTrace
23 { 24 static BeforeCommandExecute BeforeSqlCommand = null; 25 static AfterCommandExecute AfterSqlCommand = null; 26 /// <summary> 27 /// 設置DapperSql執行攔截事件 28 /// </summary> 29 /// <param name="beforeExecuteTrace">執行前事件</param> 30 /// <param name="afterExecuteTrace">執行後事件</param> 31 public static void SetMapperTrace(BeforeCommandExecute beforeExecuteTrace, AfterCommandExecute afterExecuteTrace) 32 { 33 if (null != BeforeSqlCommand) 34 return; 35 BeforeSqlCommand = beforeExecuteTrace; 36 AfterSqlCommand = afterExecuteTrace; 37 38 } 39 40 /// <summary> 41 /// 執行SQL運行前攔截事件 42 /// </summary> 43 /// <param name="traceInfo"></param> 44 internal static void ShellBeforeCommandExecute(TraceInfo traceInfo) 45 { 46 if (null != BeforeSqlCommand) 47 BeforeSqlCommand( traceInfo); 48 } 49 50 /// <summary> 51 /// 執行SQL運行成功後攔截事件,若SQL執行失敗,則此方法不會觸發 52 /// </summary> 53 /// <param name="traceInfo"></param> 54 public static void ShellAfterCommandExecute(TraceInfo traceInfo) 55 { 56 if (null != AfterSqlCommand) 57 AfterSqlCommand(traceInfo); 58 } 59 } 60 61 /// <summary> 62 /// Sql執行狀態 63 /// </summary> 64 public enum SqlState 65 { 66 /// <summary> 67 /// 執行中 68 /// </summary> 69 Start, 70 /// <summary> 71 /// 完成 72 /// </summary> 73 End, 74 /// <summary> 75 /// 失敗 76 /// </summary> 77 Error 78 } 79 80 /// <summary> 81 /// 跟蹤信息 82 /// </summary> 83 public class TraceInfo 84 { 85 /// <summary> 86 /// 操作識別Key,用用跟蹤同一SQL是否執行成功 87 /// </summary> 88 public string Token { get; set; } 89 /// <summary> 90 /// SQL語句 91 /// </summary> 92 public String CommandText { get; set; } 93 /// <summary> 94 /// sql參數 95 /// </summary> 96 public object SqlParams { get; set; } 97 98 /// <summary> 99 /// 是否正在啟動 100 /// </summary> 101 public SqlState IsStart { get; set; } 102 /// <summary> 103 /// 執行時間,性能統計,自己可根據兩次時間差去實現 104 /// </summary> 105 public DateTime ExecuteTime { get; set; } 106 107 /// <summary> 108 /// 提示信息 109 /// </summary> 110 public string Message { get; set; } 111 } 112 113 }

5、調用攔截註入

技術分享

6、特別說明:

由於Dapper中數據庫執行出錯後,不再執行 SQL執行完成事件,即(第2步的OnCompleted事件),所以在框架裏我再處理了一層

技術分享

這樣就簡單實現了SQL語句跟蹤,下一步會繼續 日誌寫入及從SQL語句中分離出 表名及執行動作,與Redis配合做緩存通知處理。

Dapper擴展SQL跟蹤及全局緩存通知