前述:

  对数据库操作的封装,相信网络上已经有一大堆,ORM框架,或者是.NET本身的EF,都很好的支持数据库操作。这篇文章是分享自己所思考的,对数据库操作的简单封装。我对于这篇文章,认为被浏览者所关注重点的是怎么分析设计数据库操作封装,代码是其次。而且,这是我第一篇文章,为了想好怎么实现花了些天,代码是博客发表时现写的。所以我想,使用可能还有bug,而且没有try catch异常的设计。

  这个框架我理应做到对数据库无关,无论是哪个数据库都能够使用。不过,重点在于分析,而不是代码。所以,为了更好的阐述,我只做了对sql Server的封装,对其他的话,浏览者可以自己设计;框架可支持链式写法,我想,在许多编程语言,大家对链式写法大不会陌生,所以我想,数据库访问也可以做成链式的模式。这个框架不需要写sql语句,对任何的操作,都只需要简单的传所需的参数,封装好对应的操作。

  在阅读文章之前最好有些泛型、反射、Link的基础,不然阅读可能会有些费劲。

进入重点:

  框架的结构比较简单,使用简单工厂模式,因此笔者就不画一张UML图来解释,而用文字对里面方法进行描述。

  在设计工厂接口时候,应该考虑接口中应该含有链式写法必须的三个阶段(也称部分):数据库基本操作(打开,关闭,创建等)、数据库的增删改查、数据库返回的数据(这里我做为执行阶段,估计大家会好奇为什么不是上一阶段,大家往下阅读就知道)和不是必须的事务操作。

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient; namespace Dal
{
public interface DbHelper
{
/// <summary>
/// 创建数据库连接
/// </summary>
/// <param name="connectionString">连接字符串</param>
/// <returns></returns>
DbHelper createConnection(string connectionString); /// <summary>
/// 打开数据库
/// </summary>
/// <returns></returns>
DbHelper openConnection(); /// <summary>
/// 关闭数据库
/// </summary>
/// <returns></returns>
DbHelper closeConnection(); /// <summary>
/// 释放sqlConnection对象
/// </summary>
void DisposedConnection(); /// <summary>
/// 释放sqlCommand对象
/// </summary>
void DisposedCommand(); /// <summary>
/// 创建sqlCommand对象
/// </summary>
/// <returns></returns>
DbHelper createCommand(); /// <summary>
/// 设置sqlCommand的类型
/// </summary>
/// <param name="type">CommandType枚举类型</param>
/// <returns></returns>
DbHelper setCommandType(CommandType type); /// <summary>
/// 要查询的表(多表以逗号隔开)、存储过程、视图名
/// </summary>
/// <param name="Name"></param>
/// <returns></returns>
DbHelper FromName(string Name); /// <summary>
/// 创建事务
/// </summary>
/// <returns></returns>
DbHelper beginTransaction(); /// <summary>
/// 事务回滚
/// </summary>
/// <returns></returns>
DbHelper TransactionRowBack(); /// <summary>
/// 事务提交
/// </summary>
/// <returns></returns>
DbHelper TransactionCommit(); /// <summary>
/// 对多张表间的列进行联系
/// </summary>
/// <param name="Fields">表间联系的字段</param>
/// <returns></returns>
DbHelper ForMulTable(string Fields); /// <summary>
/// 查询
/// </summary>
/// <param name="Fields">查询字段</param>
/// <param name="Where">查询条件字典</param>
/// <param name="otherWhere">其他条件</param>
/// <returns></returns>
DbHelper Select(string Fields = "*", Dictionary<string, object> Where = null, string otherWhere = ""); /// <summary>
/// 更新
/// </summary>
/// <param name="model">需要更新的对象</param>
/// <param name="Where">更新条件</param>
/// <param name="Fields">更新字段</param>
/// <param name="otherWhere">其他条件</param>
/// <returns></returns>
DbHelper Update(object model, Dictionary<string, object> Where, string Fields = "", string otherWhere = ""); /// <summary>
/// 插入
/// </summary>
/// <param name="model">需要插入的对象</param>
/// <param name="Fields">需要插入的字段</param>
/// <returns></returns>
DbHelper Insert(object model, string Fields = ""); /// <summary>
/// 删除
/// </summary>
/// <param name="Where">删除条件</param>
/// <param name="otherWhere">其他条件</param>
/// <returns></returns>
DbHelper Delete(Dictionary<string, object> Where, string otherWhere = ""); /// <summary>
/// 查询返回List
/// </summary>
/// <typeparam name="T">模型</typeparam>
/// <returns></returns>
List<T> ToList<T>()
where T : class ,new(); /// <summary>
/// 查询返回DataSet
/// </summary>
/// <param name="DatasetName"></param>
/// <returns></returns>
DataSet ToDataSet(string DatasetName); /// <summary>
/// 查询返回DataTable
/// </summary>
/// <returns></returns>
DataTable ToDataTable(); /// <summary>
/// 执行存储过程
/// </summary>
/// <param name="Parameter">存储过程参数</param>
/// <returns></returns>
DbHelper ExcuteProc(Dictionary<string, object> Parameter); /// <summary>
/// 执行返回查询第一行第一列值
/// </summary>
/// <returns></returns>
object Result(); /// <summary>
/// 返回执行的影响行数
/// </summary>
/// <returns></returns>
int ExcuteResult(); /// <summary>
/// 用户自定义sqlCommand
/// </summary>
/// <param name="fun">委托</param>
void UserDefineOperation(Action<dynamic> fun);
}
}

  好了,看完代码,大家对具体实现应该还是一头雾水,那,接下来一步步分析具体实现,是以sql Server来分析。

  在具体实现的类中SQLHelper,设计中所必须的字段。在一开始设计时候,我在想怎么给各个数据库兼容,因为它们使用的执行对象Command是不同的,所以为了能够更好封装的库,将其设计sqlCommand不暴露给外部使用,而是在内部使用。暴露方法能够设置com的属性,以及ExcuteName就存放着执行数据的对象。

//连接字符串
string ConnectionString; //数据库连接对象
private SqlConnection conn; //执行对象
SqlCommand com; //表、存储过程、视图名称
string ExcuteName; //事务
SqlTransaction tran; //sql语句
StringBuilder sqlBuilderString; //参数
SqlParameter[] paras;

 第一部分:数据库基本操作

  createConnection方法:这个方法其实就是new sqlConnection,对其赋值connectionString,也采用了大家一般使用的单例模式,这样也会在执行的时候比较安全。不过这个单例是指一个Helper对应一个sqlConnection,而不是设计为static,因为我觉得有些项目在访问的数据库有可能有多个。而且在创建时候,对其进行打开和关闭一次,为了检查能否真的能使用。

public DbHelper createConnection(string connectionString)
{
if (!ConnectionCanUse())
{
this.ConnectionString = connectionString;
conn = new SqlConnection(this.ConnectionString);
} return this;
} /// <summary>
/// 检查conn是否能用
/// </summary>
/// <returns></returns>
public bool ConnectionCanUse()
{
if (conn == null)
return false;
try
{
conn.Open();
conn.Close();
}catch(Exception e)
{
return false;
} return true;
}

  打开、关闭、释放connection和创建command就不作解释了,因为里面就一句话。

  关于基本操作,还有就是关于sqlCommandType的设置,因为存储过程和普通的语句等操作字符串明显是不同,因此要写个方法来设置它。

  第二部分:增删改查的操作 这里就解释为什么sql语句不是在这个阶段执行。我觉得,如果将具体的执行放在这个阶段,那么就会导致方法重载过多,为什么?因为并不是所有人都能考虑到使用者要返回的类型,比如我想要List,或者DataSet等等,而且还会将这个方法的作用过重:在我设计的这些方法中,实操作的是对sql语句的生成,所以说为什么不能在这边执行,那么就不能重用。是吧,这样设计很灵活,将数据库真正执行放在下个阶段。而且这些方法都是链式的写法,所以会对执行能够很灵活的控制,最重要能够重用,不需要写别的重载方法,只需要一个方法。

  生成sql语句在这也是简单的封装,如果要做起真的框架,我觉得sql字符串的组合还应该创建一个类,来更智能的组合用户的需求。

  自然,里面使用到反射、Linq。不过笔者也一步步解释,将怎么设计分享给大家。

  大家看到Select、Insert、Update、Delete的接口都有Where的条件字典。没错,反射就在这里使用。为了考虑到数据库的安全,所以sql自然只是简单的拼接,还应该使用参数。所以,反射就用在Where生成参数上。大家也许还看到别的otherWhere,这个怎么不设计成参数,因为Where能够实现的,其实就是赋值语句,也就是表内某字段 = 值,所以需要。在otherWhere中,存放的是其他特殊的条件。前面说这里设计的不完美,就因为如此,其实有些条件 like 或者 使用or ,虽然能够写在otherWhere中,但是没办法使用参数来控制。

  那么接下来就是Fiels参数了,这个在各个方法充当不同的作用。Select是查询的字段,Update中是更新的字段,在Insert中是插入的字段,这样就灵活的控制了。在这些字段为空的时候,默认为全部,反射在这里就使用了,遍历模型对象中的属性,然后将它们一个个填进sql语句中。在这里比较注意的应该是插入,因为大家在写sql语句时候是这样的 insert tableName values(value,value....)这样的格式,这样是因为sql会自己对应值插入,而在程序中的模型类中,我想大家写属性可不是按顺序的吧,所以在反射遍历时候,就有可能将几个本来待在某个列位置的值去换了位置的情况。所以,这里在遍历的时候,应该按插入的完全格式来设计,也就是 insert tableName(Field,Field...) values(value,value...)。

  在这几个方法中,Delete最简单。

public DbHelper Select(string Fields = "*",Dictionary<string,object> Where = null,string otherWhere = "")
{
sqlBuilderString = new StringBuilder(); sqlBuilderString.AppendLine("select " + Fields + " from " + this.ExcuteName);
List<SqlParameter> paras = new List<SqlParameter>();
sqlBuilderString.AppendLine(" where 1 = 1 "); if (Where != null && Where.Count > )
{
paras = new List<SqlParameter>();
//遍历Where,将里面的条件添加到sqlParamter和sql语句中
Where.Keys.ToList().ForEach(o => {
sqlBuilderString.AppendLine(" and "+ o + " = @" + o);
paras.Add(new SqlParameter(o, Where[o]));
});
} if(!string.IsNullOrEmpty(otherWhere))
{
sqlBuilderString.AppendLine(otherWhere);
} this.paras = paras.ToArray();
return this;
}
public DbHelper Update(object model,Dictionary<string, object> Where,string Fields = "", string otherWhere = "")
{
Type t = model.GetType();
List<string> keys = Where.Keys.ToList();
sqlBuilderString = new StringBuilder();
bool firstnode = true;
sqlBuilderString.AppendLine("update "+ExcuteName + " set ");
List<SqlParameter> paras = new List<SqlParameter>();
if(string.IsNullOrEmpty(Fields))
{
t.GetProperties().ToList().ForEach(o =>
{
if (!firstnode)
sqlBuilderString.Append(",");
else
firstnode = false;
if(!keys.Contains(o.Name))
{
sqlBuilderString.AppendLine(o.Name + " = @"+o.Name);
paras.Add(new SqlParameter(o.Name,o.GetValue(model,null)));
}
});
}else
{
Fields.Split(',').ToList().ForEach(o =>
{
sqlBuilderString.AppendLine(o + " = @" + o);
paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null)));
});
} this.paras = paras.ToArray();
return this;
}
public DbHelper Insert(object model,string Fields = "")
{
List<SqlParameter> paras = new List<SqlParameter>();
Type t = model.GetType();
sqlBuilderString = new StringBuilder();
sqlBuilderString.AppendLine("insert " + ExcuteName);
if(string.IsNullOrEmpty(Fields))
{
string s = "";
string s1="";
t.GetProperties().ToList().ForEach(o =>
{
s += o.Name + ",";
s1 += " @" + o.Name + ",";
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
});
s.Remove(s.LastIndexOf(','),);
s1.Remove(s.LastIndexOf(','), );
sqlBuilderString.AppendLine("(" + s + ")");
sqlBuilderString.AppendLine(" values(" + s1 + ")");
}else
{
sqlBuilderString.AppendLine("(" + Fields + ")");
string s = "";
Fields.Split(',').ToList().ForEach(o =>
{
s += " @" + o + ",";
paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null)));
});
sqlBuilderString.AppendLine(" values(" + s + ")");
} this.paras = paras.ToArray();
return this;
}
public DbHelper Delete(Dictionary<string,object> Where,string otherWhere = "")
{
sqlBuilderString = new StringBuilder();
List<SqlParameter> paras = new List<SqlParameter>();
sqlBuilderString.AppendLine("delete " + ExcuteName);
sqlBuilderString.AppendLine(" where 1 = 1 "); Where.Keys.ToList().ForEach(o =>
{
sqlBuilderString.AppendLine(" and " + o + " = @" + o);
paras.Add(new SqlParameter(o, Where[o]));
});
this.paras = paras.ToArray();
return this;
}

最后一个阶段,那就是执行阶段,这里封装了些执行的方法。

这个也是简单,最重要的方法应该是setCommand,这个方法是对sqlCommand进行设置,执行的语句,以及添加参数。

private void setCommand()
{
if(com.CommandType== CommandType.StoredProcedure)
{
this.com.CommandText = ExcuteName;
}else
{
this.com.CommandText = sqlBuilderString.ToString();
} this.paras.ToList().ForEach(o =>
{
this.com.Parameters.Add(o);
});
}

其他就是执行的语句。

public List<T> ToList<T>()
where T:class ,new()
{
List<T> list = new List<T>();
setCommand();
SqlDataReader reader = com.ExecuteReader();
Type t = typeof(T);
List<PropertyInfo> pros = t.GetProperties().ToList(); while(reader.Read())
{
T model = new T();
pros.ForEach(o =>
{
o.SetValue(model, reader[o.Name], null);
});
list.Add(model);
}
reader.Dispose();
return list;
} public DataSet ToDataSet(string DatasetName = "")
{
DataSet ds = new DataSet();
setCommand();
SqlDataAdapter adapter = new SqlDataAdapter(com); adapter.Fill(ds, string.IsNullOrEmpty(DatasetName) ? this.ExcuteName.Replace(",", "_") : DatasetName);
adapter.Dispose();
return ds;
} public DataTable ToDataTable()
{
DataTable dt = new DataTable();
setCommand();
SqlDataAdapter adapter = new SqlDataAdapter(com);
adapter.Fill(dt);
adapter.Dispose();
return dt;
} public object Result()
{
setCommand();
return com.ExecuteScalar();
} public int ExcuteResult()
{
setCommand();
return com.ExecuteNonQuery();
} public DbHelper ExcuteProc(Dictionary<string,object> Parameter)
{
List<SqlParameter> paras = new List<SqlParameter>(); Parameter.Keys.ToList().ForEach(o =>
{
paras.Add(new SqlParameter(o, Parameter[o]));
});
return this;
}

当然,还不能少了让用户自定义的方法,所以最后还留了个方法,参数是委托。委托里面的参数还是动态类型,这就懂了吧,想用户怎么用,你就怎么定义。

public void UserDefineOperation(Action<dynamic> fun)
{
fun(this.com);
}

好了,设计也就到这里,下面就贴上SQLHelper完整的代码。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Reflection; namespace Dal
{
public class SQLHelper:DbHelper
{
//连接字符串
string ConnectionString; //数据库连接对象
private SqlConnection conn; //执行对象
SqlCommand com; //表、存储过程、视图名称
string ExcuteName; //事务
SqlTransaction tran; //sql语句
StringBuilder sqlBuilderString; //参数
SqlParameter[] paras; private SQLHelper()
{ } /// <summary>
/// 创建sqlHelper静态方法
/// </summary>
/// <returns></returns>
public static DbHelper getInstance()
{
return new SQLHelper();
}
/// <summary>
///
/// </summary>
/// <param name="connectionString"></param>
/// <returns></returns>
public DbHelper createConnection(string connectionString)
{
if (!ConnectionCanUse())
{
this.ConnectionString = connectionString;
conn = new SqlConnection(this.ConnectionString);
} return this;
} /// <summary>
/// 检查conn是否能用
/// </summary>
/// <returns></returns>
public bool ConnectionCanUse()
{
if (conn == null)
return false;
try
{
conn.Open();
conn.Close();
}catch(Exception e)
{
return false;
} return true;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper openConnection()
{
if(conn.State != ConnectionState.Open)
this.conn.Open();
return this;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper closeConnection()
{
if(conn.State != ConnectionState.Closed)
this.conn.Close();
return this;
} /// <summary>
///
/// </summary>
public void DisposedConnection()
{
if (!ConnectionBeUsed())
this.conn.Dispose();
} /// <summary>
/// 检查数据库是否在被打开使用
/// </summary>
/// <returns></returns>
public bool ConnectionBeUsed()
{
if(conn.State == ConnectionState.Open)
return true;
return false;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper createCommand()
{
if (this.com == null)
{
this.com = new SqlCommand();
com.Connection = this.conn;
} return this;
} /// <summary>
///
/// </summary>
public void DisposedCommand()
{
this.com.Dispose();
} /// <summary>
///
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
public DbHelper setCommandType(CommandType type)
{
this.com.CommandType = type;
return this;
} /// <summary>
///
/// </summary>
/// <param name="Name"></param>
/// <returns></returns>
public DbHelper FromName(string Name)
{
this.ExcuteName = Name;
return this;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper beginTransaction()
{
this.tran = conn.BeginTransaction();
com.Transaction = this.tran;
return this;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper TransactionRowBack()
{
if(tran!=null)
{
tran.Rollback();
}
return this;
} /// <summary>
///
/// </summary>
/// <returns></returns>
public DbHelper TransactionCommit()
{
if(tran!=null)
{
tran.Commit();
tran = null;
}
return this;
} /// <summary>
///
/// </summary>
/// <param name="Fields"></param>
/// <param name="Where"></param>
/// <param name="otherWhere"></param>
/// <returns></returns>
public DbHelper Select(string Fields = "*",Dictionary<string,object> Where = null,string otherWhere = "")
{
sqlBuilderString = new StringBuilder(); sqlBuilderString.AppendLine("select " + Fields + " from " + this.ExcuteName);
List<SqlParameter> paras = new List<SqlParameter>();
sqlBuilderString.AppendLine(" where 1 = 1 "); if (Where != null && Where.Count > )
{
paras = new List<SqlParameter>();
//遍历Where,将里面的条件添加到sqlParamter和sql语句中
Where.Keys.ToList().ForEach(o => {
sqlBuilderString.AppendLine(" and "+ o + " = @" + o);
paras.Add(new SqlParameter(o, Where[o]));
});
} if(!string.IsNullOrEmpty(otherWhere))
{
sqlBuilderString.AppendLine(otherWhere);
} this.paras = paras.ToArray();
return this;
} public DbHelper ForMulTable(string Fields)
{
List<string> tables = ExcuteName.Split(',').ToList();
Fields.Split(',').ToList().ForEach(o =>
{
for(int i = ;i<tables.Count-;i++)
{
sqlBuilderString.AppendLine(" and " + tables[i] + "." + o + " = " + tables[i + ] + "." + o);
}
}); return this;
} public DbHelper Update(object model,Dictionary<string, object> Where,string Fields = "", string otherWhere = "")
{
Type t = model.GetType();
List<string> keys = Where.Keys.ToList();
sqlBuilderString = new StringBuilder();
bool firstnode = true;
sqlBuilderString.AppendLine("update "+ExcuteName + " set ");
List<SqlParameter> paras = new List<SqlParameter>();
if(string.IsNullOrEmpty(Fields))
{
t.GetProperties().ToList().ForEach(o =>
{
if (!firstnode)
sqlBuilderString.Append(",");
else
firstnode = false;
if(!keys.Contains(o.Name))
{
sqlBuilderString.AppendLine(o.Name + " = @"+o.Name);
paras.Add(new SqlParameter(o.Name,o.GetValue(model,null)));
}
});
}else
{
Fields.Split(',').ToList().ForEach(o =>
{
sqlBuilderString.AppendLine(o + " = @" + o);
paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null)));
});
} this.paras = paras.ToArray();
return this;
} public DbHelper Insert(object model,string Fields = "")
{
List<SqlParameter> paras = new List<SqlParameter>();
Type t = model.GetType();
sqlBuilderString = new StringBuilder();
sqlBuilderString.AppendLine("insert " + ExcuteName);
if(string.IsNullOrEmpty(Fields))
{
string s = "";
string s1="";
t.GetProperties().ToList().ForEach(o =>
{
s += o.Name + ",";
s1 += " @" + o.Name + ",";
paras.Add(new SqlParameter(o.Name, o.GetValue(model, null)));
});
s.Remove(s.LastIndexOf(','),);
s1.Remove(s.LastIndexOf(','), );
sqlBuilderString.AppendLine("(" + s + ")");
sqlBuilderString.AppendLine(" values(" + s1 + ")");
}else
{
sqlBuilderString.AppendLine("(" + Fields + ")");
string s = "";
Fields.Split(',').ToList().ForEach(o =>
{
s += " @" + o + ",";
paras.Add(new SqlParameter(o, t.GetProperty(o).GetValue(model, null)));
});
sqlBuilderString.AppendLine(" values(" + s + ")");
} this.paras = paras.ToArray();
return this;
} public DbHelper Delete(Dictionary<string,object> Where,string otherWhere = "")
{
sqlBuilderString = new StringBuilder();
List<SqlParameter> paras = new List<SqlParameter>();
sqlBuilderString.AppendLine("delete " + ExcuteName);
sqlBuilderString.AppendLine(" where 1 = 1 "); Where.Keys.ToList().ForEach(o =>
{
sqlBuilderString.AppendLine(" and " + o + " = @" + o);
paras.Add(new SqlParameter(o, Where[o]));
});
this.paras = paras.ToArray();
return this;
} private void setCommand()
{
if(com.CommandType== CommandType.StoredProcedure)
{
this.com.CommandText = ExcuteName;
}else
{
this.com.CommandText = sqlBuilderString.ToString();
} this.paras.ToList().ForEach(o =>
{
this.com.Parameters.Add(o);
});
} public List<T> ToList<T>()
where T:class ,new()
{
List<T> list = new List<T>();
setCommand();
SqlDataReader reader = com.ExecuteReader();
Type t = typeof(T);
List<PropertyInfo> pros = t.GetProperties().ToList(); while(reader.Read())
{
T model = new T();
pros.ForEach(o =>
{
o.SetValue(model, reader[o.Name], null);
});
list.Add(model);
}
reader.Dispose();
return list;
} public DataSet ToDataSet(string DatasetName = "")
{
DataSet ds = new DataSet();
setCommand();
SqlDataAdapter adapter = new SqlDataAdapter(com); adapter.Fill(ds, string.IsNullOrEmpty(DatasetName) ? this.ExcuteName.Replace(",", "_") : DatasetName);
adapter.Dispose();
return ds;
} public DataTable ToDataTable()
{
DataTable dt = new DataTable();
setCommand();
SqlDataAdapter adapter = new SqlDataAdapter(com);
adapter.Fill(dt);
adapter.Dispose();
return dt;
} public object Result()
{
setCommand();
return com.ExecuteScalar();
} public int ExcuteResult()
{
setCommand();
return com.ExecuteNonQuery();
} public DbHelper ExcuteProc(Dictionary<string,object> Parameter)
{
List<SqlParameter> paras = new List<SqlParameter>(); Parameter.Keys.ToList().ForEach(o =>
{
paras.Add(new SqlParameter(o, Parameter[o]));
});
return this;
} public void UserDefineOperation(Action<dynamic> fun)
{
fun(this.com);
}
}
}

最后还有两个事务的方法,前面忘记说了,其实就是SqlTransaction,在里面的sqlCommand加上这个,就可以实现。或许有人会问,如果有同一时间段有好几个sqlCommand怎么办?不会的,sqlCommand我也设置成单例,就不会发生控制不了的事情了。

  结束语:第一次的博客,我虽然做过不少“幼稚作品”,毕竟我是大三学生,如果随意的写文章,我担心只是会成为被嘲笑的对象,幼稚的“作品”也不好意思放在网上给大家看。所以,在想了几天,写了我觉得蛮有用的封装,虽然可能对许多项目不起作用,但是读者可以自己在更深的思考。

  这个框架,我觉得应该还能更好的封装,比如从sql语句组合,调用的时候发生异常处理,怎么更好的实现链式组合,多数据库的处理控制,加上锁我觉得也是可以,毕竟做web的时候可不是像winform,每个端都有自己的connection。还有一个我觉得不错的,就是在模型上做处理,加上特性,让框架能够识别主键,外键,在程序中建立sql中的联系等。那么就给读者思考了。

  现写现发表的文章应该不多,所以大家遇到什么bug可以在下面评论,欢迎大家指出不足。

C# .NET更智能的数据库操作的封装的更多相关文章

  1. C# .NET更智能的数据库操作的封装完整版(重构)

    前述: 第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路.那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考.在这两天我重构了新的框架,我觉得我写的可以称得上框架,为什么?请大 ...

  2. C# .NET更智能的数据库操作封装项目

    前面两篇文章介绍了框架的思路及里面大概的实现过程,那时候忘记上传项目,就补发一下.顺便介绍下框架使用方式,并分析下框架使用的优缺点. 先发一下前两章的链接 篇一:http://www.cnblogs. ...

  3. PHP中对数据库操作的封装

    在动态网面设计中很多都要涉及到对数据库的操作,但是有时跟据需要而改用其它后台数据库,就需要大量修改程序.这是一件枯燥.费时而且容易出错的功作.其实我们可以用PHP中的类来实现对数据库操作的封装,从而使 ...

  4. 手把手封装数据层之DataUtil数据库操作的封装

    上一篇我们写完了数据库连接的封装 没有看的请移步上一篇关于数据库连接的内容 这次我们讲数据库操作的封装.数据库的操作就是增删改查:心再大一点就可以直接分为查询和其他. 因为查询是有返回对象的,而其他都 ...

  5. django的模型类管理器-----------数据库操作的封装

    模型实例方法 str():在将对象转换成字符串时会被调用. save():将模型对象保存到数据表中,ORM框架会转换成对应的insert或update语句. delete():将模型对象从数据表中删除 ...

  6. C#对SQLite、Access数据库操作的封装,很好用的~

    1.对SQLite的封装: using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  7. oracle数据库操作 接口封装

    1.如下 using Oracle.ManagedDataAccess.Client; using System; using System.Collections.Generic; using Sy ...

  8. C# .NET数据库操作

    C# .NET更智能的数据库操作的封装完整版(重构)   前述: 第一次发表文章,不过是对数据库简单的封装,主要是阐述下思路.那么在上篇文章,在大家的指导下和提出意见,并自己对代码进行了思考.在这两天 ...

  9. ThinkPHP5.1学习笔记 数据库操作

    数据库 参见<Thinkphp5.1完全开发手册>学习 Mirror王宇阳 数据库连接 ThinkPHP采用内置抽象层对数据库操作进行封装处理:且基于PDO模式,可以适配各种数据库. 数据 ...

随机推荐

  1. web前端好学吗?

    最近这段时间许多学生讨论关于WEB前端工程师这个职位的问题.比如:关于前端难不难?好不好找工作?有没有用?好不好学?待遇好不好?好不好转其他的职位? 针对这个问题,课工场露露老师想跟大家谈谈自己对前端 ...

  2. c#和java中的方法覆盖——virtual、override、new

    多态和覆盖 多态是面向对象编程中最为重要的概念之一,而覆盖又是体现多态最重要的方面.对于像c#和java这样的面向对象编程的语言来说,实现了在编译时只检查接口是否具备,而不需关心最终的实现,即最终的实 ...

  3. shell 创建带参数的命令方法

    主要用到case in,和shift命令. shift 命令是从参数数组中,删除当前第一个参数. while [ "$1" != "" ] do case $1 ...

  4. ie6和ie7下z-index bug的解决办法

    一.匆匆带过的概念 关于CSS中层级z-index的定义啊什么的不是本文的重点,不会花费过多篇幅详细讲述.这里就简单带过,z-index伴随着层的概念产生的.网页 中,层的概念与photoshop或是 ...

  5. Angular - - $location 和 $window

    $location $location服务解析浏览器地址中的url(基于window.location)并且使url在应用程序中可用.将地址栏中的网址的变化反映到$location服务和$locati ...

  6. redhat5安装phantomjs

    Linux 64-bit Download phantomjs-2.1.1-linux-x86_64.tar.bz2 (22.3 MB) and extract the content. Note: ...

  7. [ Android 五种数据存储方式之三 ] —— SQLite存储数据

    SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP, Python)都使用了 ...

  8. 数组(Array)资源

    上面的程序中在Java代码中定义了两个数组,Android并不推荐在Java代码中定义数组,因为Androd允许通过资源文件来定义数组资源. Android采用位于/res/values目录下的arr ...

  9. HDU-1754-I Hate It(线段树,简单,不过好像有点问题)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1754 题目不难,不过开始我犯了一个低级错误,输入n,m,m代表操作的数目,我没有写了,写代码的时候,就 ...

  10. 树莓派VNC搭建相关问题,啦啦啦~

    为了节省money,于是我决定用VNC界面来代替显示器,为后面做C++ Qt以及Python Qt开发打下基础,我别无选择!下面开始进入正题: 1-- 下载VNC-Viewer-6.0.1-Windo ...