以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是计算而来的,但很明显它听起来像是一个属性而非方法 ...
随机推荐
- JavaScript私有方法
some concepts: Java is from Sun Microsystem Inc., and JavaScript, called LiveScript before, is from ...
- 【Oracle】Rman简介
1.备份和恢复功能的用途: –保护数据 -介质故障 -用户错误 -应用程序错误 –数据保存和历史数据保留 –数据传输 2.典型的备份和恢复任务 –通过配置数据库实现可恢复 –定义备份计划 –对不同类型 ...
- 模拟试题C
模拟试题C 一.单项选择题(2′*14 =28′) 1.双线性法向插值法(Phong Shading)的优点是( ) A)法向计算精确 B)高光域准确 C)对光源和视点没有限制 D)速度较快 2.用编 ...
- Debian 6 , 十个串口为什么只识别到了 6个 剩下4 个被禁止了
0.946441] Serial: 8250/16550 driver, 6 ports, IRQ sharing enabled [ 0.946533] serial8250: ttyS0 a ...
- mongoDB 介绍(特点、优点、原理)
介绍:MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. 特点:高性能.易部署.易使用,存储数据非常方便. 主要功能特性有: Ø 面 ...
- 洛谷P2038 无线网络发射器选址 水题 枚举
刚开始边界写错了(将128写成127). 注意n <= 20,所以可以每读入一个点就将其周边更新,这样最多也只会有 40 * 40 * 20 种位置需要被枚举. Code: #include&l ...
- EL表达式中,param和requestScope的区别
在看param和requestScope之前,不妨先了解下在java下request的情况: 1. request对象通常用来接收客户端提交到服务端的数据,如:在servlet或者action中可以用 ...
- FFMpeg 常用命令格式转换,视频合成
FFmpeg都是命令行的,用起来肯定不方便.但是,这对技术宅应该不成问题.下面,我就罗列一些比较实用的使用方法吧. FFmpeg的下载与安装 FFmpeg是开源的.但我们不必去下载它的源代码.下载已经 ...
- CF786A - Berzerk
/* CF786A - Berzerk http://codeforces.com/contest/786/problem/A 博弈论 直接搜出NP状态图.记得要记忆化剪枝. * */ #includ ...
- 计算机网络系统--常用DOS命令
01.名称:md 用法:md “文件夹名” 用处:批量建立文件夹 02.关机命令 shutdown At 18:00 shutdown –s 18:00关机 shutdown -s -t 3 ...