zoukankan      html  css  js  c++  java
  • 写出易调试的SQL(修订版)

    1.前言

    上篇 写出易调试的SQL , 带来了一些讨论, 暴露了不能重用执行计划和sql注入问题, 十分感谢园友们的建议 .

    经过调整后 ,将原来的SQLHelper 抓SQL 用做调试环境用, 发布环境还是走Dapper的参数化查询, 保持原有优势.

    见如下代码.

    2. 在开发调试阶段 抓最终SQL

     将Dapper 查询Query 和执行Execute 进行了再包装, 插入了 抓最终sql 的代码

     public class DapperTaller
        {
    
            /// <summary>
            /// dapper 执行查询 sql
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <returns></returns>
            public static IEnumerable<T> Query<T>(string sql, object param)
            {
                IEnumerable<T> result = null;
                using (var con = DBHelper.GetConnection())
                {
                    result = con.Query<T>(sql, param);
                }
    
                //开发环境代码
                if (GlobalVariable.env.IsDevelopment()) //IsDevelopment 方法为Asp.NET Core 自带的 是否为开发环境的判断方法
                {
                    //最终SQL
                    var debugSql = GetDebugSQL(sql, param);
                    Debug.WriteLine(debugSql);
                }
    
                return result;
            }
    
            /// <summary>
            /// dapper 执行 增加, 删除 ,修改 sql
            /// </summary>
            /// <param name="sql"></param>
            /// <param name="param"></param>
            /// <returns></returns>
            public static int Execute(string sql, object param)
            {
                int result;
                using (var con = DBHelper.GetConnection())
                {
                    result = con.Execute(sql, param);
                }
    
                //开发环境代码
                if (GlobalVariable.env.IsDevelopment()) //IsDevelopment 方法为Asp.NET Core 自带的 是否为开发环境的判断方法
                {
                    //最终SQL
                    var debugSql = GetDebugSQL(sql, param);
                    Debug.WriteLine(debugSql);
                }
    
                //生产环境代码
                if (GlobalVariable.env.IsProduction())
                {
                    //根据需要将最终SQL 记录到日志
    
                }
    
                return result;
            }
    
            public static string GetDebugSQL(string sql, object param)
            {
                var sqlHelper = new SqlHelper();
                foreach (var item in param.GetType().GetProperties())
                {
                    var name = item.Name;
                    var value = item.GetValue(param);
                    sqlHelper.Param.Add(name, value);
                }
    
                sqlHelper.ReplaceParam(ref sql);
                return sql;
            }
    
    
        }
    
        public class DBHelper
        {
            public static IDbConnection GetConnection()
            {
                return SQLServerHelper.GetConnection();
            }
        }

    调用代码:

     public IEnumerable<Ptype> GetPtypeDetail()
            {
                var sql = @"
     SELECT 
        * 
     FROM dbo.CoacherStudentMoney a
     INNER JOIN dbo.BaseData b ON a.CourseTypeId=b.Id
     WHERE 
     StudentUserId=@StudentUserId AND Amount=@Amount
     AND IsPay=@IsPay AND CreateDate=@CreateDate
     
    ";
                var param = new
                {
                    StudentUserId = "001",
                    CreateDate = DateTime.Now,
                    Amount = 3,
                    IsPay = true
                };
    
                IEnumerable<Ptype> plist = new List<Ptype>();
                plist = DapperTaller.Query<Ptype>(sql, param);
    
                return plist;
            }

    最上面代码的此处为最终SQL 抓取

              //开发环境代码
                if (GlobalVariable.env.IsDevelopment())
                {
                    //最终SQL
                    var debugSql = GetDebugSQL(sql, param);
                    Debug.WriteLine(debugSql);
                }
        

    并且会在VS 的输出窗口输出

    进一步方便了调试.

    3.最后

    现在最终SQL 的抓取发生在 调试开发阶段 .

    发布代码后, 将不会进行最终SQL的抓取. 并且走的还是Dapper 原有参数化查询的方式, 依旧拥有执行计划重用, 防SQL注入的优势.

    注:

    完整可执行代码见: https://pan.baidu.com/s/1jI4YcQi    

    本文代码是 AnuoApc.Data 项目下的 -> Dapper目录下的 ->  DapperTaller.cs 文件, 可从这里开始看

    作者: 蒋奎

    博客: http://www.cnblogs.com/anuo/

    欢迎转载,请在明显位置给出出处及链接

  • 相关阅读:
    [CodeForces]Codeforces Round #429 (Div. 2) ABC(待补)
    About Me
    2018-06-14
    Codeforces Codeforces Round #484 (Div. 2) E. Billiard
    Codeforces Codeforces Round #484 (Div. 2) D. Shark
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) F. Isomorphic Strings
    Codeforces Educational Codeforces Round 44 (Rated for Div. 2) E. Pencils and Boxes
    Codeforces Avito Code Challenge 2018 D. Bookshelves
    Codeforces Round #485 (Div. 2) D. Fair
    Codeforces Round #485 (Div. 2) F. AND Graph
  • 原文地址:https://www.cnblogs.com/anuo/p/6256673.html
Copyright © 2011-2022 走看看