以SqlHelper为例论面向对象中封装的使用
引言: 在使用面向对象方法编写的程序中,会有一些工具类,如Utility,xxHelper等。 比如1)操作数据库的过程,一般步骤都是:1.准备数据库地址、表名等信息;2.建立连接;3.准备要执行sql语句或存储过程;4.设置执行参数;5.执行sql语句;6.读取执行结果;7.处理异常、关闭连接、释放资源。 再比如2)联网获取/发送数据的过程,一般步骤都是:1.准备Url,设置连接方式及参数;2.建立连接;3.发送请求;4.读取请求结果;5.处理异常、关闭连接、释放资源。 对比以上两个操作我们发现:对于建立连接发送请求的这种操作,有很大一部分的工作时前期准备工作和善后工作,且这些工作在每次请求时基本相同。
本文将以SqlHelper对ADO.NET的封装为例,探讨一下面向对象中封装的使用。
下面展示一小段使用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 string
return 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 execution
SqlCommand 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 it
if (connection.State != ConnectionState.Open)
{
connection.Open();
} //associate the connection with the command
command.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 type
command.CommandType = commandType; //attach the command parameters if they are provided
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
} return;
}
这样封装处理之后,每次再操作起数据库来就方便许多了。这就是面向对象中封装的使用,这种思想通过示例代码来阐述因该比较容易理解了吧。
以SqlHelper为例论面向对象中封装的使用的更多相关文章
- 以SqlHelper为例论面向对象中封装的使用(续)
上文以SqlHelper为例说明了面向对象中封装的好处,但是上文只是简单封装,考虑下面代码的情况: public static Activate GetByCode(string code) { Li ...
- Python面向对象中的继承、多态和封装
Python面向对象中的继承.多态和封装 一.面向对象的三大特性 封装:把很多数据封装到⼀个对象中,把固定功能的代码封装到⼀个代码块, 函数,对象, 打包成模块. 这都属于封装思想. 继承:⼦类可以⾃ ...
- C++中对C的扩展学习新增内容———面向对象(封装)
面向对象(封装) 1.对封装的理解: 1.封装就是把变量和函数放在一起统一表示某一个食物. class 2.给类内部的成员增加访问控制权限. 3.封装的语法就是class定义一个类. 2.给对象成员增 ...
- OracleHelper(对增删改查分页查询操作进行了面向对象的封装,对批量增删改操作的事务封装)
公司的一个新项目使用ASP.NET MVC开发,经理让我写个OracleHelper,我从网上找了一个比较全的OracleHelper类,缺点是查询的时候返回DataSet,数据增删改要写很多代码(当 ...
- 黑马程序员_Java面向对象1_封装
3.面向对象_封装 3.1面向对象概念 3.1.1理解面向对象 面向对象是相对面向过程而言 面向对象和面向过程都是一种思想 面向过程:强调的是功能行为(执行者) 面向对象:将功能封装进对象,强调具备了 ...
- Java面向对象(封装性概论)
Java面向对象(封装性概论) 知识概要: (1)面向对象概念 (2)类与对象的关系 (3)封装 (4)构造函数 (5)this关键字 (6)static关键 ...
- python 面向对象之封装与类与对象
封装 一,引子 从封装本身的意思去理解,封装就好像是拿来一个麻袋,把小猫,小狗,小王八,小老虎一起装进麻袋,然后把麻袋封上口子.照这种逻辑看,封装='隐藏',这种理解是相当片面的 二,先看如何隐藏 在 ...
- python面向对象编程 -- 封装、继承
面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...
- python之路----面向对象中的内置函数
property属性 什么是特性property property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值 例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法 ...
随机推荐
- 整理Py小demo
from email.mime.text import MIMEText # 第一个参数就是邮件正文,第二个参数是MIME的subtype, # 传入'plain'表示纯文本,最终的MIME就是'te ...
- WebService 服务接口
天气预报Web服务,数据来源于中国气象局Endpoint :http://www.webxml.com.cn/WebServices/WeatherWebService.asmxDisco :http ...
- SqlServer与MySql 系统表查询自建表数据
SqlServer: SELECT * FROM sys.sysobjects WHERE type='U' ORDER BY name SELECT * FROM sys.syscolumns WH ...
- vim 常用操作笔记
跳转最后一行 :$ 或 shift+g 跳转第一行 :1 或 gg 设置自动换行 :set wrap 设置不自动换行 :set nowrap
- 应运而生! 双11当天处理数据5PB—HiStore助力打造全球最大列存储数据库
阿里巴巴电商业务中历史数据存储与查询相关业务, 大量采用基于列存储技术的HiStore数据库,双11当天HiStore引擎处理数据记录超过6万亿条.原始存储数据量超过5PB.从单日数据处理量上看,该系 ...
- concurrently - npm 同时运行前端和后台服务
项目基于vue(前端)+node(后台),需要启动两个服务 0.文件夹结构及package.json内容: 1.客户端 npm run dev 2.服务器 cd server npm run serv ...
- Exact Change FreeCodeCamp
function checkCashRegister(price, cash, cid) { var change; var sumCid = 0; // Here is your change, m ...
- a标记地址的几种用法
1.<a href="tel://号码"></a> 手机使用能自动拨打电话 //可以省略 2.<a href="mailto://邮箱&qu ...
- Python笔记7----Pandas中变长字典Series
1.Series概念 类似一维数组的对象,由数据和索引组成 2.Series创建 用Series()函数创建,0,1,2为series结构自带的索引. 可以自己指定索引值,用index,也可以直接用字 ...
- 搞定PHP面试 - 变量知识点整理
一.变量的定义 1. 变量的命名规则 变量名可以包含字母.数字.下划线,不能以数字开头. $Var_1 = 'foo'; // 合法 $var1 = 'foo'; // 合法 $_var1 = 'fo ...