看了下以前写的代码,有很多重复的地方,于是就想到用类把它们封装起来
建立了一个SQLHelper的类
首先是 ExcuteNonQuery()
public static int ExcuteNonQuery(string sql,params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText =sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteNonQuery();
}
}
}
这里用到了 params,值得注意的是params 必须放在参数列表中最后面的位置
然后是ExcuteScalar()
public static object ExcuteScalar(string sql, params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteScalar();
}
}
}
接下来是ExcuteReader()
//SqlDataReader对于小数据量来说带来的只有麻烦,优点可以忽略不计
//ADO.net中提供了数据集的机制,将查询结果填充到本地内存中,这样连接断开服务器都不影响数据的读取
/*不能用这个方法,因为出了using之后 reader就断开了
public static SqlDataReader ExcuteReader(string sql, params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
return cmd.ExecuteReader();
}
}
}
*/
调用这个函数的时候发现了一个很严重的问题,在using作用域结束的时候会关闭reader,那就不能调用了。嗯,Dataset类,它是将数据库中的table复制到内存中,这样调用的时候就可以不管服务器的开关。
所以用ExcuteDataTable()取代了ExcuteDataReader()
public static DataTable ExcuteDataTable(string sql, params SqlParameter[] parameters)
{
string connStr = ConfigurationManager.ConnectionStrings["ConnStr"].ConnectionString;
using (SqlConnection conn = new SqlConnection(connStr))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = sql;
foreach (SqlParameter parameter in parameters)
{
cmd.Parameters.Add(parameter);
}
DataSet dataset = new DataSet();
SqlDataAdapter adapter = new SqlDataAdapter(cmd);
adapter.Fill(dataset);
return dataset.Tables[0];
}
}
用这个类写了一个登陆程序,代码确实比以前简化了很多
private void btnLogin_Click(object sender, EventArgs e)
{
DataTable dt = SQLHelper.ExcuteDataTable("Select * from T_Users where UserName=@Username",new SqlParameter("Username",txtUserName.Text));
if (dt.Rows.Count <= 0)
{
MessageBox.Show("用户名不存在");
}
else
{
DataRow row = dt.Rows[0];
int errorTimes = Convert.ToInt32(row["ErrorTimes"]);
if (errorTimes >= 3)
{
MessageBox.Show("错误次数过多");
return;
}
string dbPassword = Convert.ToString(row["Password"]);
if (dbPassword == txtPassword.Text)
{
SQLHelper.ExcuteNonQuery("update T_Users set ErrorTimes=0 where UserName=@Username",new SqlParameter("Username",txtUserName.Text));
MessageBox.Show("登陆成功");
}
else
{
MessageBox.Show("密码错误");
SQLHelper.ExcuteNonQuery("update T_Users set ErrorTimes=ErrorTimes+1 where UserName=@Username",new SqlParameter("Username",txtUserName.Text));
}
}
}
界面依旧很简单~