从基础开始,从一个SQLHelper开始

时间:2022-12-12 20:55:15

最开始考虑的问题有这三点:

1.Access和SQLServer都要能用。

2.尽量简单,清晰。

3.性能不出大问题。

    public class SQLHelp
{
#region 私有域 private static string ConnStr = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
private static string ProviderType = ConfigurationManager.AppSettings["ProviderType"].ToString();
private DbConnection _Conn;
private static DbProviderFactory DbFactory=DbProviderFactories.GetFactory(ProviderType);
private DbCommand _Cmd = DbFactory.CreateCommand(); private string _CmdText;
private CommandType _CmdType;
#endregion
#region 属性
private DbConnection Conn
{
get
{ return _Conn; }
set
{ _Conn = value; }
} public DbCommand Cmd
{
get { return _Cmd; }
set { _Cmd = value; }
}
public string CmdText
{
get { return _CmdText; }
set
{
_CmdText = value;
_Cmd.CommandText = value;
}
} public CommandType CmdType
{
get { return _CmdType; }
set
{
_CmdType = value;
_Cmd.CommandType = value;
}
}
#endregion
#region 私有方法
private void OpenCon()
{
try
{
if (Conn == null)
{
Conn = DbFactory.CreateConnection();
}
if (Conn.State == ConnectionState.Closed)
{
Conn.ConnectionString = ConnStr;
Conn.Open();
}
}
catch (Exception ex)
{ throw (new Exception("打开数据库出错,错误" + ex.Message));
}
}
private void CloseCon()
{
if (Conn.State == ConnectionState.Open)
{
Conn.Close();
}
}
#endregion
/// <summary>
/// 执行指定的SQL语句(如添加、更新、删除等操作)
/// </summary>
/// <returns>受影响的行数</returns>
public int ExecuteNonQuery()
{
OpenCon();
try
{
return Cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw (new Exception("数据库执行错误: " + ex.Message));
}
finally
{ CloseCon();
}
} /// <summary>
/// 使用 DataAdapter 提取数据返回为 DataTable,并为 DataTable 指定名称
/// </summary>
/// <returns>DataTable</returns>
public DataTable ExecuteDataTable()
{
OpenCon();
try
{
using (DbDataAdapter da =DbFactory.CreateDataAdapter())
{
da.SelectCommand = Cmd;
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
catch (Exception ex)
{
throw (new Exception("数据库执行错误:" + ex.Message));
}
finally
{
CloseCon();
}
}
  }
}

写的过程发现了很多问题:每个属性该不该静态,赋初值在哪里进行,属性的写法是否合适,需不需要构造函数。最主要的疑惑:SQL语句执行完了立即释放Cmd好,还是等多条都用同一个Cmd执行好。

然后发邮件给一位学长,学长回复:

问题1、看场合决定用什么工厂,抽象工厂或工厂方法。
问题2、连接和命令都是用完立即释放。按你的做法,会一直占用数据库的连接资源,SQL SERVER的连接数本来就少,这种做法个人觉得不好。
问题3、这个问题干脆不回答了。我建议你看看ADO.NET的思想,考虑它为何提供连接后又提供断开连接。断开连接的产生就是为了让你读取完数据后马上释放连接资源。你反复连接是没问题的,因为有连接池在管理。

代码方面
异常处理我是在程序中作统一处理,辅助类中不加异常处理代码。

这是改后的第二版:

 public class SQLHelp
{
#region 私有域 private static string ConnStr = ConfigurationManager.ConnectionStrings["SqlConnection"].ConnectionString;
private static string ProviderType = ConfigurationManager.AppSettings["ProviderType"].ToString();
private DbConnection _Conn;
private static DbProviderFactory DbFactory=DbProviderFactories.GetFactory(ProviderType);
private DbCommand _Cmd; private string _CmdText;
private CommandType _CmdType = CommandType.Text;
#endregion
#region 属性
private DbConnection Conn
{
get
{ return _Conn; }
set
{ _Conn = value; }
} public DbCommand Cmd
{
get { return _Cmd; }
set { _Cmd = value; }
}
public string CmdText
{
get { return _CmdText; }
set { _CmdText = value;}
} public CommandType CmdType
{
get { return _CmdType; }
set { _CmdType = value; }
}
#endregion
#region 私有方法
private void OpenCon()
{
try
{
if (Conn == null)
{
Conn = DbFactory.CreateConnection();
}
if (Conn.State == ConnectionState.Closed)
{
Conn.ConnectionString = ConnStr;
Conn.Open();
}
}
catch (Exception ex)
{ throw (new Exception("打开数据库出错,错误" + ex.Message));
}
}
private void CloseCon()
{
if (Conn.State == ConnectionState.Open)
{
Conn.Close();
}
if (Cmd != null)
{
Cmd.Dispose();
Cmd = null;
}
}
private void StartCommend()
{
OpenCon();
Cmd = Conn.CreateCommand();
Cmd.CommandText = CmdText;
Cmd.CommandType = CmdType;
}
#endregion
/// <summary>
/// 执行指定的SQL语句(如添加、更新、删除等操作)
/// </summary>
/// <returns>受影响的行数</returns>
public int ExecuteNonQuery()
{
StartCommend();
try
{
return Cmd.ExecuteNonQuery();
}
catch (Exception ex)
{
throw (new Exception("数据库执行错误: " + ex.Message));
}
finally
{
CloseCon();
}
} /// <summary>
/// 使用 DataAdapter 提取数据返回为 DataTable,并为 DataTable 指定名称
/// </summary>
/// <returns>DataTable</returns>
public DataTable ExecuteDataTable()
{
StartCommend();
try
{
using (DbDataAdapter da =DbFactory.CreateDataAdapter())
{
da.SelectCommand = Cmd;
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
catch (Exception ex)
{
throw (new Exception("数据库执行错误:" + ex.Message));
}
finally
{
CloseCon();
}
}
  }
}

对有些概念依然模糊,需要每次执行完语句就直接断开链接吗?这里面的哪些写法不对?

求各位指教。

从基础开始,从一个SQLHelper开始的更多相关文章

  1. 自己写的一个SqlHelper&comma;感觉使用起来挺方便的

    自己写的一个SqlHelper,感觉使用起来挺方便的 using System; using System.Data; using System.Collections.Generic; using ...

  2. &lpar;C&num;&rpar;Windows Shell 编程系列1 - 基础,浏览一个文件夹

    原文 (C#)Windows Shell 编程系列1 - 基础,浏览一个文件夹 (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) Windows Shell 编程,即 Windows ...

  3. JAVA&lowbar;SE基础——5&period;第一个Java程序HelloWorld&注释的应用

    配置完JDK&环境变量后,我们就可以开始写程序了,那么程序怎么写呢,用什么工具呢,我建议 为了方便学习,我们最好在一个磁盘下建立一个专门的文件来写java程序,比如就在D盘下建立一个名为&qu ...

  4. &lpar;C&num;&rpar;Windows Shell 外壳编程系列1 - 基础,浏览一个文件夹

    1 - 基础,浏览一个文件夹 我们知道,在win32中是以外壳名字空间的形式来组织文件系统的,在外壳名字空间里的每一个对象(注)都实现了一个IShellFolder的接口,通过这个接口我们可以直接查询 ...

  5. Jmeter使用基础笔记-写一个http请求

    前言 本篇文章主要讲述2个部分: 搭建一个简单的测试环境 用Jmeter发送一个简单的http请求 搭建测试环境 编写flask代码(我参考了开源项目HttpRunner的测试服务器),将如下的代码保 ...

  6. RPC基础以及造一个RPC的*需要注意些什么

    RPC基础以及造一个RPC的*需要注意些什么 前言 rpc即远程过程调用,是分布式系统常用的通信方法.远程可以是在一台机器上的不同进程或在不同一个机器上的不同进程.rpc更看重速度,像调用本地方法一 ...

  7. 【云开发】10分钟零基础学会做一个快递查询微信小程序,快速掌握微信小程序开发技能(轮播图、API请求)

    大家好,我叫小秃僧 这次分享的是10分钟零基础学会做一个快递查询微信小程序,快速掌握开发微信小程序技能. 这篇文章偏基础,特别适合还没有开发过微信小程序的童鞋,一些概念和逻辑我会讲细一点,尽可能用图说 ...

  8. Vue&period;js基础篇实战--一个ToDoList小应用

    距离开始学Vue已经过去一个多月了,总想把学到的东西柔和在一起,做点东西出来,于是有了这个Todolist小应用. 使用vuex 纯粹基础,没有用到web pack,vuex,npm,下次把它改造一下 ...

  9. 《Entity Framework 6 Recipes》翻译系列 &lpar;3&rpar; -----第二章 实体数据建模基础之创建一个简单的模型

    第二章 实体数据建模基础 很有可能,你才开始探索实体框架,你可能会问“我们怎么开始?”,如果你真是这样的话,那么本章就是一个很好的开始.如果不是,你已经建模,并在实体分裂和继承方面感觉良好,那么你可以 ...

随机推荐

  1. Java 在指定目录建立指定文件名的文件 并输入内容

    package runoob; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream ...

  2. Qt实现小功能之列表无限加载

    概念介绍 无限加载与瀑布流的结合在Web前端开发中的效果非常新颖,对于网页内容具备较好的表现形式.无限加载并没有一次性将内容全部加载进来,而是通过监听滚动条事件来刷新内容的.当用户往下拖动滚动条或使用 ...

  3. Ubuntu回收站

    以前删除文件经常Move to trash,今天想清空发现根本不知道回收站在哪里,囧.遂Google之,于是发现在 -/.local/share/Trash目录下. 打开目录看看有什么东西: ➜ ~ ...

  4. &lbrack;转&rsqb;面向GPU的多LOD因子的大规模场景可视化策略

    直接附上原文链接: 1.面向GPU的多LOD因子的大规模场景可视化策略 2.Real-Time Dynamic Level of Detail Terrain Rendering with ROAM

  5. Java笔记&lpar;二十四&rpar;&hellip&semi;&hellip&semi;集合工具类Collections&amp&semi;Arrays

    Collections 集合框架的工具类,方法全部为静态 Collections与Collection的区别 Collection是集合框架的一个顶层接口,里面定义了单列集合的共性方法 Collect ...

  6. javascript prototype &lowbar;&lowbar;proto&lowbar;&lowbar;区别

    An Object's __proto__ property references the same object as its internal [[Prototype]] (often refer ...

  7. 好看的复选框(Checkbox)效果

    在线演示      源码下载

  8. github上传代码返回403错误

    报错代码: ****************   表示上传的项目地址 remote: Permission to Jayson00/camera.git denied to Minelinkinpar ...

  9. windows查看进程占用并强制结束进程

    打开命令提示符(CMD) 查看8080端口被哪个进程占用了,命令:netstat   -ano|findstr 8080 上面的8080端口的PID是30160,可以根据PID可以杀死这个进程,用下面 ...

  10. Windows10锁屏壁纸提取

    CMD执行:  %localappdata%\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\As ...