• 利用Attribute简化SQL删除操作


      昨天跟朋友聊天,发现他们的项目数据层使用的是最基础的纯SQL语句+SqlParameter进行数据交互的,大家知道SELECT、UPDATE、CREATE对于表的依赖性比较大,然后删除语句却不一样,它的语法比较简单,大致有以下几种:

      1、DELETE FROM TableName

      2、DELETE FROM TableName WHERE ID = idValue

      3、DELETE FROM TableName WHERE ID IN (id1, id2, id3, id4....)

      于是我们要实现这个简单的功能来简化比较常用的删除就比较容易了,主要保留2个数据,1个是TableName,另外1个就是ID了,如果实体类有基类的情况下,我们可以扩展基类,提供2个接口,让其他的实体类去实现来保存对应的TableName和ID。但是如果没有基类的话,我们也可以利用Attribute来实现这个功能。

      Attribute代码如下:

     1 [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    2 public class DbAttribute : Attribute
    3 {
    4 #region 变量
    5
    6 private string m_TableName = null;
    7
    8 private string m_PrimaryKey = null;
    9
    10 #endregion
    11
    12 #region 构造函数
    13
    14 public DbAttribute(string tableName, string primaryKey)
    15 {
    16 this.m_TableName = tableName;
    17 this.m_PrimaryKey = primaryKey;
    18 }
    19
    20 #endregion
    21
    22 #region 普通方法
    23
    24 public string GetDeleteAllSQL()
    25 {
    26 return string.Format(@"
    27 DELETE
    28 FROM
    29 {0}", this.m_TableName);
    30 }
    31
    32 /// <summary>
    33 /// 获取根据主键删除表数据
    34 /// </summary>
    35 /// <typeparam name="TParam">数据库类型</typeparam>
    36 /// <typeparam name="TPKValue">主键类型名</typeparam>
    37 /// <param name="tPKValue">主键值</param>
    38 /// <returns></returns>
    39 public KeyValuePair<string, TParam[]> GetDeleteByPrimaryKeySQL<TParam, TPKValue>(TPKValue tPKValue)
    40 where TParam : DbParameter, new()
    41 {
    42 var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
    43 WHERE
    44 {0} = :_pk_", this.m_PrimaryKey));
    45 MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
    46 var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
    47 {
    48 {"_pk_", tPKValue}
    49 });
    50 return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
    51 }
    52
    53 /// <summary>
    54 /// 获取根据主键数组删除表数据
    55 /// </summary>
    56 /// <typeparam name="TParam"></typeparam>
    57 /// <typeparam name="TPKValue"></typeparam>
    58 /// <param name="arrTPKValue"></param>
    59 /// <returns></returns>
    60 public KeyValuePair<string, TParam[]> GetDeleteInPrimaryKeySQL<TParam, TPKValue>(params TPKValue[] arrTPKValue)
    61 where TParam : DbParameter, new()
    62 {
    63 var sql = string.Concat(this.GetDeleteAllSQL(), string.Format(@"
    64 WHERE
    65 {0} IN (:_arr_pk_)", this.m_PrimaryKey));
    66 MarkParameter<TParam> markParameter = new MarkParameter<TParam>();
    67 var arrDbParam = markParameter.CastMark(ref sql, new Hashtable
    68 {
    69 {"_arr_pk_", arrTPKValue}
    70 });
    71 return new KeyValuePair<string, TParam[]>(sql, arrDbParam);
    72 }
    73
    74 #endregion
    75 }

      以上用到泛型模式以及前几篇文章提到的替换参数的方法,文章在此。有了以上的Attribute,我们就可以用它来标记实体类了,代码如下: 

    1 [Db("Permission_Info", "p_id")]
    2 public partial class Permission
    3 {
    4 //属性、方法等
    5 }

      为了演示,我写了一个用来调用的方法,来测试产生的语句和参数。测试类代码如下:

     1 public class DbOperate
    2 {
    3 public static string GetDeleteSQL<TClass>() where TClass : new()
    4 {
    5 var attr = GetAttribute<TClass>();
    6 var sql = string.Empty;
    7 if (null != attr)
    8 {
    9 sql = attr.GetDeleteAllSQL();
    10 }
    11 return sql;
    12 }
    13
    14 public static KeyValuePair<string, SqlParameter[]> GetDeleteByIdSQL<TClass, TPKValUe>(params TPKValUe[] arrTPKValue) where TClass : new()
    15 {
    16 var attr = GetAttribute<TClass>();
    17 KeyValuePair<string, SqlParameter[]> pair = new KeyValuePair<string, SqlParameter[]>(null, null);
    18 if (null != attr)
    19 {
    20 if (1 == arrTPKValue.Length)
    21 {
    22 pair = attr.GetDeleteByPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue[0]);
    23 }
    24 else
    25 {
    26 pair = attr.GetDeleteInPrimaryKeySQL<SqlParameter, TPKValUe>(arrTPKValue);
    27 }
    28 }
    29 return pair;
    30 }
    31
    32 static DbAttribute GetAttribute<T>() where T : new()
    33 {
    34 var arrAttribute = typeof(T).GetCustomAttributes(typeof(DbAttribute), false);
    35 DbAttribute attr = null;
    36 if (0 < arrAttribute.Length)
    37 {
    38 attr = arrAttribute[0] as DbAttribute;
    39 }
    40 return attr;
    41 }
    42 }

      代码测试如下:

      以上代码并不是最优的选择,我们仍然可以在Attribute调用的地方进行优化,大家可以参考老赵的《Attribute操作的性能优化方式》

  • 相关阅读:
    vue比较模板来跟新数据
    iframe自适应高度
    springmvc接口ios网络请求
    spring mvc实现接口参数统一更改
    spring mvc实现自定义注解
    基于redis集群实现的分布式锁,可用于秒杀,定时器。
    java使用javax.mail进行免费的邮件发送
    前端图片压缩上传(纯js的质量压缩,非长宽压缩)
    java项目中的路径获取,request
    阿里云(腾讯云类似)服务器控制台配置开放所有的端口
  • 原文地址:https://www.cnblogs.com/ahl5esoft/p/2340935.html
Copyright © 2020-2023  润新知