zoukankan      html  css  js  c++  java
  • 重构ConditionHelper

      在上一篇日志写了ConditionHelper的具体实现方法和它的用法,但那时只是把心里所想的一个思路用代码记录下来,而没有经过实践检 验的,难免存在一些问题,但在最近的一个新项目中用到ConditionHelper时,才发现其中问题不少,最简单的问题是方法名取得有问题,如 AddAndCondition、AddOrCondition等,不注意的话很容易弄错,所以在重构的过程把这些方法合并成了一个方法,另外还有在使用 时如遇到一些特殊情况还会出错,在重构后把这些问题都修复了,至少用了一两个星期了没有发现新的Bug,但也不能保证不存在Bug了,只能说应该基本是没 什么问题了。

      在使用ConditionHelper的过程中,自己觉得比以前用的方法方便很多了,写出来的代码也精简了不少,看着都舒服些。

       以前本来想着改进后直接把上一篇日志修改一下就行了,但自己觉得重构后的代码与重构前的代码有很大的区别,所以想着也没必要把以前不好的东西直接一笔抹 杀,这样也方便以后看看其中的区别。自己最近在重新写框架时,看着以前写的框架有很多地方是写得很啰嗦的,但自己当时并没有这么觉得,有时代码隔一段时间 回头来看你就会发现原来还可以这样精简一下,这并不一定是水平提高的原因,人有时一心放在一件事情上反而不能把事情做好,偶尔把自己的视线移到别的地方, 再回头来看,也许你会发觉原来还可以这样子写。

      好了,废话不多说了,以下是重构后的全部代码:      

    1     #region  public enum Comparison
      2     public enum Comparison
      3     {
      4         /// <summary>
      5         /// 等于号 =
      6         /// </summary>
      7         Equal,
      8         /// <summary>
      9         /// 不等于号 <>
     10         /// </summary>
     11         NotEqual,
     12         /// <summary>
     13         /// 大于号 >
     14         /// </summary>
     15         GreaterThan,
     16         /// <summary>
     17         /// 大于或等于 >=
     18         /// </summary>
     19         GreaterOrEqual,
     20         /// <summary>
     21         /// 小于 <
     22         /// </summary>
     23         LessThan,
     24         /// <summary>
     25         /// 小于或等于 <=
     26         /// </summary>
     27         LessOrEqual,
     28         /// <summary>
     29         /// 模糊查询 Like
     30         /// </summary>
     31         Like,
     32         /// <summary>
     33         /// 模糊查询  Not Like
     34         /// </summary>
     35         NotLike,
     36         /// <summary>
     37         /// is null
     38         /// </summary>
     39         IsNull,
     40         /// <summary>
     41         /// is not null
     42         /// </summary>
     43         IsNotNull,
     44         /// <summary>
     45         /// in
     46         /// </summary>
     47         In,
     48         /// <summary>
     49         /// not in
     50         /// </summary>
     51         NotIn,
     52         /// <summary>
     53         /// 左括号 (
     54         /// </summary>
     55         OpenParenthese,
     56         /// <summary>
     57         /// 右括号 )
     58         /// </summary>
     59         CloseParenthese,
     60         Between,
     61         StartsWith,
     62         EndsWith
     63     }
     64     #endregion
     65 
     66     #region public enum RelationType
     67     /// <summary>
     68     /// 关联类型:And、Or
     69     /// </summary>
     70     public enum RelationType
     71     {
     72         AND,
     73         OR,
     74     }
     75     #endregion
     76 
     77 
     78     /// <summary>
     79     /// 文件名:ConditionHelper
     80     /// 功能描述:条件帮助类
     81     /// </summary>
     82     public class ConditionHelper
     83     {
     84         #region 变量、属性定义
     85         string parameterPrefix = "@";
     86         string parameterKey = "P";
     87         /// <summary>
     88         /// 用来拼接SQL语句
     89         /// </summary>
     90         StringBuilder conditionBuilder = new StringBuilder();
     91         /// <summary>
     92         /// 为True时表示字段为空或者Null时则不作为查询条件
     93         /// </summary>
     94         bool isExcludeEmpty = true;
     95         /// <summary>
     96         /// 是否生成带参数的sql
     97         /// </summary>
     98         bool isBuildParameterSql = true;
     99 
    100         #region public List<SqlParameter> ParameterList
    101         private List<SqlParameter> parameterList = new List<SqlParameter>();
    102         /// <summary>
    103         /// 参数列表
    104         /// </summary>
    105         public List<SqlParameter> ParameterList
    106         {
    107             get { return this.parameterList; }
    108         } 
    109         #endregion
    110 
    111         int index = 0;
    112 
    113         #endregion
    114 
    115         #region 构造函数
    116         /// <summary>
    117         /// 创建ConditionHelper对象
    118         /// </summary>
    119         /// <param name="isExcludeEmpty">为True时表示字段为空或者Null时则不作为查询条件</param>
    120         /// <param name="isBuildParameterSql">是否生成带参数的sql</param>
    121         /// <param name="parameterKey">参数的前辍</param>
    122         public ConditionHelper(bool isExcludeEmpty = true, string parameterKey = "P", bool isBuildParameterSql = true)
    123         {
    124             this.isExcludeEmpty = isExcludeEmpty;
    125             this.isBuildParameterSql = isBuildParameterSql;
    126             this.parameterKey = parameterKey;
    127             this.conditionBuilder.Append(" Where ");
    128         }
    129         #endregion
    130 
    131         #region 公共方法
    132         #region  public ConditionHelper Clear()  清除已添加的条件
    133         /// <summary>
    134         /// 清除已添加的条件
    135         /// </summary> 
    136         /// <returns></returns>
    137         public ConditionHelper Clear()
    138         {
    139             parameterList.Clear();
    140             conditionBuilder.Clear().Append(" Where ");
    141             return this;
    142         }
    143         #endregion
    144 
    145         #region public ConditionHelper AppendCondition(RelationType relationType, string fieldName, Comparison comparison, params object[] fieldValue) 添加条件
    146         /// <summary>
    147         /// 添加条件
    148         /// </summary>
    149         /// <param name="relationType">关联运算符</param>
    150         /// <param name="comparison">比较符类型</param>
    151         /// <param name="fieldName">字段名称</param>
    152         /// <param name="fieldValue">字段值,注:1、不可为数组;2、Between时,此字段必须填两个值; </param>
    153         /// <returns>返回ConditionHelper</returns>
    154         public ConditionHelper AppendCondition(RelationType relationType, string fieldName, Comparison comparison, params object[] fieldValue)
    155         {
    156             if (IsContinue(fieldValue)) return this;
    157 
    158             if (!this.conditionBuilder.ToString().Trim().EndsWith("WHERE", StringComparison.InvariantCultureIgnoreCase))
    159             {
    160                 this.conditionBuilder.Append(GetRelationString(relationType));
    161             }
    162             this.AppendCondition(fieldName, comparison, fieldValue);
    163             return this;
    164         }
    165         #endregion
    166 
    167         #region public ConditionHelper AppendCondition(string fieldName, Comparison comparison, params object[] fieldValue)
    168         /// <summary>
    169         /// 添加条件
    170         /// </summary>
    171         /// <param name="comparison">比较符类型</param>
    172         /// <param name="fieldName">字段名称</param>
    173         /// <param name="fieldValue">字段值,注:1、不可为数组;2、Between时,此字段必须填两个值; </param>
    174         /// <returns>返回ConditionHelper</returns>
    175         public ConditionHelper AppendCondition(string fieldName, Comparison comparison, params object[] fieldValue)
    176         {
    177             if (IsContinue(fieldValue)) return this;
    178 
    179             switch (comparison)
    180             {
    181                 case Comparison.Equal:
    182                 case Comparison.NotEqual:
    183                 case Comparison.GreaterThan:
    184                 case Comparison.GreaterOrEqual:
    185                 case Comparison.LessThan:
    186                 case Comparison.LessOrEqual:
    187                     this.conditionBuilder.AppendFormat("{0}{1}{2}", GetFieldName(fieldName), GetComparisonOperator(comparison), GetFieldValue(fieldValue[0]));
    188                     break;
    189                 case Comparison.IsNull:
    190                 case Comparison.IsNotNull:
    191                     this.conditionBuilder.AppendFormat("{0}{1}", GetFieldName(fieldName), GetComparisonOperator(comparison));
    192                     break;
    193                 case Comparison.Like:
    194                 case Comparison.NotLike:
    195                     this.conditionBuilder.AppendFormat("{0}{1}{2}", GetFieldName(fieldName), GetComparisonOperator(comparison), GetFieldValue(string.Format("%{0}%", fieldValue[0])));
    196                     break;
    197                 case Comparison.In:
    198                 case Comparison.NotIn:
    199                     this.conditionBuilder.AppendFormat("{0}{1}({2})", GetFieldName(fieldName), GetComparisonOperator(comparison), string.Join(",", GetFieldValue(fieldValue)));
    200                     break;
    201                 case Comparison.StartsWith:
    202                     this.conditionBuilder.AppendFormat("{0}{1}{2}", GetFieldName(fieldName), GetComparisonOperator(comparison), GetFieldValue(string.Format("{0}%", fieldValue[0])));
    203                     break;
    204                 case Comparison.EndsWith:
    205                     this.conditionBuilder.AppendFormat("{0}{1}{2}", GetFieldName(fieldName), GetComparisonOperator(comparison), GetFieldValue(string.Format("%{0}", fieldValue[0])));
    206                     break;
    207                 case Comparison.Between:
    208                     this.conditionBuilder.AppendFormat("{0}{1}{2} AND {3}", GetFieldName(fieldName), GetComparisonOperator(comparison), GetFieldValue(fieldValue[0]), GetFieldValue(fieldValue[1]));
    209                     break;
    210                 default:
    211                     throw new Exception("条件为定义");
    212             }
    213             return this;
    214         }
    215         #endregion
    216 
    217         #region public ConditionHelper AppendParenthese(RelationType relationType, ConditionHelper condition)
    218         /// <summary>
    219         /// 添加含有括号的条件
    220         /// </summary>
    221         /// <param name="relationType">关联运算符</param>
    222         /// <param name="condition">条件</param>
    223         /// <returns></returns>
    224         public ConditionHelper AppendParenthese(RelationType relationType, ConditionHelper condition)
    225         {
    226             if (condition == null || condition.conditionBuilder.ToString().Trim().Length < 6)
    227                 return this;
    228             if (!conditionBuilder.ToString().Trim().EndsWith("WHERE", StringComparison.InvariantCultureIgnoreCase))
    229             {
    230                 this.conditionBuilder.Append(GetRelationString(relationType));
    231             }
    232             this.conditionBuilder.AppendFormat(" ({0}) ", condition.conditionBuilder.ToString().Remove(0, 6));
    233             if (condition.parameterList.Count > 0)
    234             {
    235                 this.parameterList.AddRange(condition.parameterList);
    236             }
    237             return this;
    238         }
    239         #endregion
    240 
    241         #region public override string ToString()
    242         /// <summary>
    243         /// 转化成Sql条件语句:(包含Where关键字)
    244         /// </summary>
    245         /// <returns></returns>
    246         public override string ToString()
    247         {
    248             if (this.conditionBuilder.Length < 8)
    249                 return string.Empty;
    250             return this.conditionBuilder.ToString();
    251         }
    252         #endregion
    253 
    254         #endregion
    255 
    256 
    257         #region 私有方法
    258         /// <summary>
    259         /// 取得字段值
    260         /// </summary>
    261         /// <param name="fieldValue"></param>
    262         /// <returns></returns>
    263         private string GetFieldValue(params object[] fieldValue)
    264         {
    265             if (isBuildParameterSql == true)
    266             {
    267                 if (fieldValue.Length < 2)
    268                 {
    269                     return AddParameter(fieldValue[0]);
    270                 }
    271                 else
    272                 {
    273                     List<string> parameterNameList = new List<string>();
    274                     foreach (var value in fieldValue)
    275                     {
    276                         parameterNameList.Add(AddParameter(value));
    277                     }
    278                     return string.Join(",", parameterNameList);
    279                 }
    280             }
    281             else
    282             {
    283                 if (fieldValue.Length < 2)
    284                 {
    285                     return string.Format("'{0}'", fieldValue[0]);
    286                 }
    287                 else
    288                 {
    289                     return string.Format("'{0}'", string.Join("','", fieldValue));
    290                 }
    291             }
    292         }
    293 
    294         /// <summary>
    295         /// 添加参数
    296         /// </summary>
    297         /// <param name="fieldValue"></param>
    298         /// <returns></returns>
    299         private string AddParameter(object fieldValue)
    300         {
    301             index++;
    302             string parameterName = string.Format("{0}{1}{2}", parameterPrefix, parameterKey, index);
    303             this.parameterList.Add(new SqlParameter
    304              {
    305                  ParameterName = parameterName,
    306                  Value = fieldValue ?? DBNull.Value
    307              });
    308             return parameterName;
    309         }
    310 
    311         private string GetFieldName(string fieldName)
    312         {
    313             return string.Format("{0}", fieldName);
    314         }
    315 
    316         /// <summary>
    317         /// 用来判断是否跳过此拼接条件
    318         /// </summary>
    319         /// <param name="fieldValue">字段值</param>
    320         /// <returns>返回True表示跳过,否则不跳过</returns>
    321         private bool IsContinue(params object[] fieldValue)
    322         {
    323             bool result = false;
    324             //如果选择IsExcludeEmpty为True,并且该字段为空值的话则跳过
    325             if (isExcludeEmpty && fieldValue != null && fieldValue.Length > 0 && string.IsNullOrEmpty(fieldValue[0] + ""))
    326                 result = true;
    327             return result;
    328         }
    329 
    330         /// <summary>
    331         /// 取得关联类型字符串
    332         /// </summary>
    333         /// <param name="relationType"></param>
    334         /// <returns></returns>
    335         private static string GetRelationString(RelationType relationType)
    336         {
    337             string result = string.Empty;
    338             switch (relationType)
    339             {
    340                 case RelationType.AND:
    341                     result = SqlKeyWords.AND;
    342                     break;
    343                 case RelationType.OR:
    344                     result = SqlKeyWords.OR;
    345                     break;
    346             }
    347             return result;
    348         }
    349 
    350         /// <summary>
    351         /// 取得关系运算符
    352         /// </summary>
    353         /// <param name="comparison"></param>
    354         /// <returns></returns>
    355         private static string GetComparisonOperator(Comparison comparison)
    356         {
    357             string result = string.Empty;
    358             switch (comparison)
    359             {
    360                 case Comparison.Equal:
    361                     result = " = ";
    362                     break;
    363                 case Comparison.NotEqual:
    364                     result = " <> ";
    365                     break;
    366                 case Comparison.GreaterThan:
    367                     result = " > ";
    368                     break;
    369                 case Comparison.GreaterOrEqual:
    370                     result = " >= ";
    371                     break;
    372                 case Comparison.LessThan:
    373                     result = " < ";
    374                     break;
    375                 case Comparison.LessOrEqual:
    376                     result = " <= ";
    377                     break;
    378                 case Comparison.Like:
    379                 case Comparison.StartsWith:
    380                 case Comparison.EndsWith:
    381                     result = " LIKE ";
    382                     break;
    383                 case Comparison.NotLike:
    384                     result = " NOT LIKE ";
    385                     break;
    386                 case Comparison.IsNull:
    387                     result = " IS NULL ";
    388                     break;
    389                 case Comparison.IsNotNull:
    390                     result = " IS NOT NULL ";
    391                     break;
    392                 case Comparison.In:
    393                     result = " IN ";
    394                     break;
    395                 case Comparison.NotIn:
    396                     result = " NOT IN ";
    397                     break;
    398                 case Comparison.OpenParenthese:
    399                     result = " (";
    400                     break;
    401                 case Comparison.CloseParenthese:
    402                     result = ") ";
    403                     break;
    404                 case Comparison.Between:
    405                     result = " BETWEEN ";
    406                     break;
    407                 default:
    408                     throw new Exception("条件未定义!");
    409             }
    410             return result;
    411         }
    412         #endregion
    413 
    414     }
    View Code

       重构后添加条件的方法就只有AppendCondition和AppendCondition的重载以及AppendParenthese三个方法,方法名字把Add改为Append,总觉得Add做为方法名有点怪怪的,AppendParenthese为添加含有括号的条件,在上一篇日志中的ConditionHelper中关于括号的条件组合是存在问题的,有时存在添加了左括号而没有右括号的情况,在重构号把左右括号放在一个方法里就不存在这个问题了。另外根据自己项目的需要,添加了Clear方法,以便清除先前添加进去的条件。

      以下是我在一个项目中用到ConditionHelper的一个例子:

      

     1         /// <summary>
     2         /// 通过登录账号和密码查找用户
     3         /// </summary>
     4         /// <param name="userID">登录账号</param>
     5         /// <param name="password">加密前的密码</param>
     6         /// <returns>返回用户信息</returns>
     7         public SysUserInfo FindByUser(string userID, string password)
     8         {
     9             if (string.IsNullOrEmpty(userID))
    10                 return null;
    11             password = Encrypt(password);
    12             ConditionHelper condition = new ConditionHelper();
    13             condition.AppendCondition(SysUserInfo.F_UserID, Comparison.Equal, userID)
    14                      .AppendCondition(RelationType.AND, SysUserInfo.F_Password, Comparison.Equal, password);
    15             return this.Find(condition);
    16         }
    View Code
  • 相关阅读:
    二次识别
    IPC
    HW
    数据库异常:SQL Error: 0, SQLState: S0022
    mysql 分页查询
    [Err] 1248
    名句摘抄
    理智向左 疯狂向右
    kindle怎么导入电子书
    设置 myeclipse 编码格式
  • 原文地址:https://www.cnblogs.com/Lau7/p/4714574.html
Copyright © 2011-2022 走看看