以SqlHelper为例论面向对象中封装的使用

来源:互联网 发布:淘宝店铺联盟分享店铺 编辑:程序博客网 时间:2024/04/30 03:33

在使用面向对象方法编写的程序中,会有一些工具类,如Utility,xxHelper等。


比如1)操作数据库的过程,一般步骤都是:

1.准备数据库地址、表名等信息;2.建立连接;3.准备要执行sql语句或存储过程;4.设置执行参数;5.执行sql语句;6.读取执行结果;7.处理异常、关闭连接、释放资源。

再比如2)联网获取/发送数据的过程,一般步骤都是:

1.准备Url,设置连接方式及参数;2.建立连接;3.发送请求;4.读取请求结果;5.处理异常、关闭连接、释放资源。


对比以上两个操作我们发现:对于建立连接发送请求的这种操作,有很大一部分的工作时前期准备工作和善后工作,且这些工作在每次请求时基本相同。


下面展示一小段使用ADO.NET(一组向 .NET Framework 程序员公开数据访问服务的类)操作数据库的代码:

private void button1_Click(object sender, EventArgs e){//前期准备工作string connetionString = null;SqlConnection cnn ;SqlCommand cmd ;string sql = null;connetionString = "Data Source=ServerName;Initial Catalog=DatabaseName;User ID=UserName;Password=Password";sql = "Your SQL Statemnt Here";cnn = new SqlConnection(connetionString);try{cnn.Open();cmd = new SqlCommand(sql, cnn);//执行cmd.ExecuteNonQuery();//善后工作cmd.Dispose();cnn.Close();MessageBox.Show (" ExecuteNonQuery in SqlCommand executed !!");}catch (Exception ex){MessageBox.Show("Can not open connection ! ");}}

可以看到大量的前期准备工作和善后工作的代码(我称之为“边缘代码”),而真正执行请求的代码只有一句话。在一个应用中,我们需要操作数据库的地方可能不下数十次,如果每一次操作数据库都复制粘贴一遍这些“边缘代码”,那样不仅代码写起来累人,看着也很低端。而且如果有一天需要改变连接数据库的设置时,几十处内容都需要重新复制粘贴一遍,不管你能不能受了,我是受不了。


所以便有了“封装”这一举动,把这些细节封装到一个类中(不妨叫SqlHelper),操作数据库时我们希望这些“边缘代码”自动执行。下面代码便是一个简单封装的结果:

//使用SqlHelper封装后public static void Insert(ServiceCall serviceCall){List<SqlParameter> paraList = new List<SqlParameter>();paraList.Add(new SqlParameter("@url",serviceCall.Url));paraList.Add(new SqlParameter("@payload",serviceCall.Payload));SqlHelper.ExecuteNonQuery(Configuration.ConnectionString, CommandType.StoredProcedure, "InsertServiceCallLog", paraList.ToArray());}
封装后的代码清爽了许多!我们只传了必要的3个参数(数据库地址,sql语句,参数)给工具类(SqlHelper),其余的建立连接,设置参数,释放资源等都在工具类(SqlHelper)中悄悄的做了,是不是很爽?!

这只是一次简单的尝试,看这个封装类是怎么实现的:
//内部实现public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters){//create & open a SqlConnection, and dispose of it after we are done.using (SqlConnection cn = new SqlConnection(connectionString)){cn.Open();//call the overload that takes a connection in place of the connection stringreturn ExecuteNonQuery(cn, commandType, commandText, commandParameters);}}public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters){//create a command and prepare it for executionSqlCommand cmd = new SqlCommand();PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters);//finally, execute the command.int retval = cmd.ExecuteNonQuery();// detach the SqlParameters from the command object, so they can be used again.cmd.Parameters.Clear();return retval;}

依然是建立连接,打开链接,设置参数,执行语句,善后处理这个过程。

private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters){//if the provided connection is not open, we will open itif (connection.State != ConnectionState.Open){connection.Open();}//associate the connection with the commandcommand.Connection = connection;//set the command text (stored procedure name or SQL statement)command.CommandText = commandText;//if we were provided a transaction, assign it.if (transaction != null){command.Transaction = transaction;}//set the command typecommand.CommandType = commandType;//attach the command parameters if they are providedif (commandParameters != null){AttachParameters(command, commandParameters);}return;}

这样封装处理之后,每次再操作起数据库来就方便许多了。这就是面向对象中封装的使用,这种思想通过示例代码来阐述因该比较容易理解了吧。



0 0
原创粉丝点击