Dapper 封装02-组装SQL

qshpeng 2020-07-26

在 SQLSERVER 里,我们在执行命令的时候我们是可以进行参数化传递的。这个好处主要可以防止注入。

定义接受参数的类:

public class DataParameter
    {
        public DataParameter()
        {
        }
        public DataParameter(string name,object value)
        {
            this.Name = name;
            this.Value = value;
        }
        public string Name { get; set; }
        public object Value { get; set; }
    }

我们正常写一个 Where 语句,比如 WHERE Age=23 and name like ‘%delaywu%‘ 。从这句话中我们知道一个where 表达式 是由 表字段名 + 操作符号 + 值  组成的基本操作。

所以我们创建一个方法来构建这样的SQL

private static WhereClip BuildWhereChip(string propertyName, object value, QueryOper op, string paramName=null)
        {
            if(op !=QueryOper.IsNull && op!=QueryOper.IsNotNull && (value==null || value==DBNull.Value))
            {
                return null;
            }
            WhereClip where = new WhereClip();
            StringBuilder sbSql = new StringBuilder($"{propertyName}{SqlQueryUtils.ToString(op)}");

            if (value !=null && value !=DBNull.Value)
            {
                if(paramName ==null)
                {
                    paramName = SqlQueryUtils.GetParmName(propertyName);
                }

                if(paramName.Length>0)
                {
                    sbSql.Append($"@{paramName}");
                    where.Parameters.Add(new DataParameter(paramName, value));
                }
                else
                {
                    sbSql.Append($"{value}");
                } 
            }
            where.WhereSql = sbSql.ToString();
            return where;
        }
public static string GetParmName(string propertyName)
        {
            //[a.name]="delaywu"
            string paramName = propertyName.Replace("[", "").Replace("]", "");
            if(paramName.Contains("."))
            {
                //name
                int lstIdx = paramName.LastIndexOf(‘.‘);
                paramName = paramName.Substring(lstIdx + 1).Trim();
            }
            if(!System.Text.RegularExpressions.Regex.IsMatch(paramName,"^[a-zA-Z1-9_]*$"))
            {
                return string.Empty;
            }
            return paramName;
        }
GetParmName 这个方法主要是 可能在写多表查询的时候出现 a.Name b.age 这类的情况。获得其真实的 字段名称。以及[  ] 这个信息的处理。有了基础的构建方法。我们可以把相关操的符的 WHERE 都可以生成出来了。
public static WhereClip Eq(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.Eq, paramName);
        }

        public static WhereClip NotEq(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.NotEq, paramName);
        }

        public static WhereClip IsNull(string propertyName)
        {
            return BuildWhereChip(propertyName, null, QueryOper.IsNull, null);
        }
        public static WhereClip IsNotNull(string propertyName)
        {
            return BuildWhereChip(propertyName, null, QueryOper.IsNotNull, null);
        }
        public static WhereClip StartWith(string propertyName, string value, string paramName = null)
        {
            return Like(propertyName, value.Replace("%", "[%]").Replace("_", "[_]") + ‘%‘, paramName);
        } 
        public static WhereClip EndsWith(string propertyName, string value, string paramName = null)
        {
            return Like(propertyName, ‘%‘ + value.Replace("%", "[%]").Replace("_", "[_]"), paramName);
        }

        public static WhereClip Gt(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.Gt, paramName);
        }
        public static WhereClip Lt(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.Lt, paramName);
        }
        public static WhereClip Le(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.Le, paramName);
        }
        public static WhereClip Ge(string propertyName, object value, string paramName = null)
        {
            return BuildWhereChip(propertyName, value, QueryOper.Ge, paramName);
        }
        public static WhereClip Like(string propertyName, string value, string paramName = null)
        {
            if (string.IsNullOrEmpty(value))
            {
                return null;
            }
            return BuildWhereChip(propertyName, value, QueryOper.Like, paramName);
        }

        public static WhereClip Between(string propertyName, object lo, object hi,  string paramName=null)
        {
            WhereClip where = new WhereClip();
            StringBuilder sbSql = new StringBuilder($"{propertyName} between ");
            if(paramName==null)
            {
                paramName = SqlQueryUtils.GetParmName(propertyName);
            }
            if(propertyName.Length>0)
            {
                string strParamName1 = paramName + "_pmin";
                string strParamName2 = paramName + "_pmax";
                sbSql.Append($"@{strParamName1} and @{strParamName2} ");
                where.Parameters.Add(new DataParameter(strParamName1, lo));
                where.Parameters.Add(new DataParameter(strParamName2, hi));
            }
            else
            {
                sbSql.Append($"{lo} and {hi}");
            }
            where.WhereSql = sbSql.ToString();
            return where;
        }

        public static WhereClip DapperIn<T>(string propertyName,IEnumerable<T>values,string paramName=null)
        {
            if (values == null || !values.Any())
            {
                return null;
            }

            WhereClip where = new WhereClip();
            if(paramName==null)
            {
                paramName = SqlQueryUtils.GetParmName(propertyName);
            }
            if(paramName.Length>0)
            {
                where.Parameters.Add(new DataParameter(paramName, values));
                where.WhereSql = $"{propertyName} in @{paramName} ";
            }
            else
            {
                if(typeof(T).FullName==typeof(string).FullName)
                {
                    string strIn = string.Join<T>("‘,‘", values);
                    where.WhereSql = $"{propertyName} in ({strIn})";
                }
                else
                {
                    string strIn = string.Join<T>(",", values);
                    where.WhereSql = $"{propertyName} in ({strIn})";
                }
            }
            return where;
        }

        public static WhereClip DapperNotIn<T>(string propertyName, IEnumerable<T> values, string paramName = null)
        {
            if (values == null || !values.Any())
            {
                return null;
            }
            WhereClip where = new WhereClip();
            if (paramName == null)
            {
                paramName = SqlQueryUtils.GetParmName(propertyName);
            }
            if (paramName.Length > 0)
            {
                where.Parameters.Add(new DataParameter(paramName, values));
                where.WhereSql = $"{propertyName} not in @{paramName} ";
            }
            else
            {
                if (typeof(T).FullName == typeof(string).FullName)
                {
                    string strIn = string.Join<T>("‘,‘", values);
                    where.WhereSql = $"{propertyName} not in (‘{strIn}‘) ";
                }
                else
                {
                    string strIn = string.Join<T>(",", values);
                    where.WhereSql = $"{propertyName} not in ({strIn}) ";
                }
            }
            return where;
        }

上面的代码。我主要说一下 Like 相关的。数据库里面我们经常使用 []来转义特殊的单词。like 中%我们是要转义的,其次_也要的。

Dapper 封装02-组装SQL

测试一下:

Dapper 封装02-组装SQL

相关推荐