以前只用一种数据库,倒也无所谓,但是再数据库切换的时候,发现代码差不多呀。

最初,两种数据库,大不了写两个SqlHelper,但是多了也就发现代码重用率太低了吧。

因此,下面的SqlHelper诞生了。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text; namespace WangSql.DBUtility
{
public static class SqlHelperExt
{
public static int AddRange(this IDataParameterCollection coll, IDataParameter[] par)
{
int i = ;
foreach (var item in par)
{
coll.Add(item);
i++;
}
return i;
}
} #region SqlHelper
public class SqlHelper
{
private IDbConnection conn = null;
private IDbCommand cmd = null;
private IDataReader dr = null;
private DbType type = DbType.NONE; #region 创建数据库连接
/// <summary>
/// 创建数据库连接
/// </summary>
public SqlHelper(string connectionString)
{
conn = DBFactory.CreateDbConnection(type, connectionString);
}
#endregion #region 判断并打开conn
/// <summary>
/// 判断并打开conn
/// </summary>
/// <returns></returns>
public IDbConnection CreatConn()
{
if (conn.State == ConnectionState.Closed)
{
conn.Open();
}
return conn;
}
#endregion #region 执行查询sql语句
/// <summary>
/// 执行查询sql语句
/// </summary>
/// <param name="sql">查询sql语句</param>
/// <returns>返回一个表</returns>
public DataTable ExecuteReader(string sql)
{
DataTable dt = new DataTable();
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
using (dr = cmd.ExecuteReader())
{
dt.Load(dr);
}
}
conn.Close();
return dt;
}
#endregion #region 执行查询带参的sql语句
/// <summary>
/// 执行查询带参的sql语句
/// </summary>
/// <param name="sql">查询sql语句</param>
/// <param name="par">sql语句中的参数</param>
/// <returns>返回一个表</returns>
public DataTable ExecuteReader(string sql, IDataParameter[] par)
{
DataTable dt = new DataTable();
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
cmd.Parameters.AddRange(par);
using (dr = cmd.ExecuteReader())
{
dt.Load(dr);
}
}
conn.Close();
return dt;
}
public DataTable ExecuteReader(string sql, IDataParameter par)
{
DataTable dt = new DataTable();
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
cmd.Parameters.Add(par);
using (dr = cmd.ExecuteReader())
{
dt.Load(dr);
}
}
conn.Close();
return dt;
}
#endregion #region 执行增,删,改sql语句
/// <summary>
/// 执行无参的增,删,改sql语句
/// </summary>
/// <param name="sql">增,删,改的sql语句</param>
/// <param name="par">sql语句中的参数</param>
/// <returns>返回所影响的行数</returns>
public int ExecuteNonQuery(string sql)
{
int result = ;
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
result = cmd.ExecuteNonQuery();
}
conn.Close();
return result;
}
#endregion #region 执行带参的增,删,改sql语句
/// <summary>
/// 执行带参的增,删,改sql语句
/// </summary>
/// <param name="sql">增,删,改的sql语句</param>
/// <param name="par">sql语句中的参数</param>
/// <returns>返回所影响的行数</returns>
public int ExecuteNonQuery(string sql, IDbDataParameter[] par)
{
int result = ;
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
cmd.Parameters.AddRange(par);
result = cmd.ExecuteNonQuery();
}
conn.Close();
return result;
}
public int ExecuteNonQuery(string sql, IDbDataParameter par)
{
int result = ;
using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
{
cmd.Parameters.Add(par);
result = cmd.ExecuteNonQuery();
}
conn.Close();
return result;
}
#endregion #region 事务
/// <summary>
/// 执行多条SQL语句,实现数据库事务。
/// </summary>
/// <param name="SQLList">SQL语句的哈希表(key为sql语句,value是该语句的OleDbParameter[])</param>
public bool ExecuteTransaction(Hashtable SqlList)
{
CreatConn();
using (IDbTransaction trans = conn.BeginTransaction())
{
IDbCommand cmd = DBFactory.CreateDbCommand(type);
try
{
//循环
foreach (DictionaryEntry myDE in SqlList)
{
string cmdText = myDE.Key.ToString();
IDbDataParameter[] cmdParms = (IDbDataParameter[])myDE.Value;
PrepareCommand(cmd, conn, trans, cmdText, cmdParms);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
}
trans.Commit();
}
catch
{
trans.Rollback();
return false;
}
finally
{
conn.Close();
}
}
return true;
} private void PrepareCommand(IDbCommand cmd, IDbConnection conn, IDbTransaction trans, string cmdText, IDataParameter[] cmdParms)
{
CreatConn();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (trans != null)
cmd.Transaction = trans;
cmd.CommandType = CommandType.Text;//cmdType;
if (cmdParms != null)
cmd.Parameters.AddRange(cmdParms);
}
#endregion
}
#endregion
}

上面是核心代码,上面有个扩展。主要是是由于抽象类里面不包含AddRange方法。楼主也是懒得改原来的方法,也是为了和原来的SqlHelper保持一致,干脆就直接扩展了一个AddRange。

好了,既然是全是抽象参数,实际中,还是需要实例化具体某种数据库的实例的,所以还需要一个创建各个数据库实例的工厂了。

using MySql.Data.MySqlClient;
using Oracle.DataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.Linq;
using System.Text; namespace WangSql
{
public enum DbType
{
//Oracle,SqlServer,MySql,Access,SqlLite
NONE,
ORACLE,
SQLSERVER,
MYSQL,
ACCESS,
SQLLITE
} public class DBFactory
{
public static IDbConnection CreateDbConnection(DbType type, string connectionString)
{
IDbConnection conn = null;
switch (type)
{
case DbType.ORACLE:
conn = new OracleConnection(connectionString);
break;
case DbType.SQLSERVER:
conn = new SqlConnection(connectionString);
break;
case DbType.MYSQL:
conn = new MySqlConnection(connectionString);
break;
case DbType.ACCESS:
conn = new OleDbConnection(connectionString);
break;
case DbType.SQLLITE:
conn = new SQLiteConnection(connectionString);
break;
case DbType.NONE:
throw new Exception("未设置数据库类型");
default:
throw new Exception("不支持该数据库类型");
}
return conn;
} public static IDbCommand CreateDbCommand(DbType type)
{
IDbCommand cmd = null;
switch (type)
{
case DbType.ORACLE:
cmd = new OracleCommand();
break;
case DbType.SQLSERVER:
cmd = new SqlCommand();
break;
case DbType.MYSQL:
cmd = new MySqlCommand();
break;
case DbType.ACCESS:
cmd = new OleDbCommand();
break;
case DbType.SQLLITE:
cmd = new SQLiteCommand();
break;
case DbType.NONE:
throw new Exception("未设置数据库类型");
default:
throw new Exception("不支持该数据库类型");
}
return cmd;
}
public static IDbCommand CreateDbCommand(string sql, IDbConnection conn)
{
DbType type = DbType.NONE;
if (conn is OracleConnection)
type = DbType.ORACLE;
else if (conn is SqlConnection)
type = DbType.SQLSERVER;
else if (conn is MySqlConnection)
type = DbType.MYSQL;
else if (conn is OleDbConnection)
type = DbType.ACCESS;
else if (conn is SQLiteConnection)
type = DbType.SQLLITE; IDbCommand cmd = null;
switch (type)
{
case DbType.ORACLE:
cmd = new OracleCommand(sql, (OracleConnection)conn);
break;
case DbType.SQLSERVER:
cmd = new SqlCommand(sql, (SqlConnection)conn);
break;
case DbType.MYSQL:
cmd = new MySqlCommand(sql, (MySqlConnection)conn);
break;
case DbType.ACCESS:
cmd = new OleDbCommand(sql, (OleDbConnection)conn);
break;
case DbType.SQLLITE:
cmd = new SQLiteCommand(sql, (SQLiteConnection)conn);
break;
case DbType.NONE:
throw new Exception("未设置数据库类型");
default:
throw new Exception("不支持该数据库类型");
}
return cmd;
} }
}

哈哈,即使再来一个数据库,你试试看,是不是很简单呢。

对了,上面的SqlHelper再单例模式下是有问题的哦,这个请大家提出下好的建议。

万能的SqlHelper,麻麻再也不用担心用什么数据库了的更多相关文章

  1. zzulioj--1841--so easy!麻麻再也不用担心我的数学了!(数学水题)

    1841: so easy!麻麻再也不用担心我的数学了! Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 27  Solved: 15 SubmitSt ...

  2. 一个App带你学会Retrofit2.0,麻麻再也不用担心我的网络请求了!

    Retrofit.Retrofit.Retrofit,越来越多的人在玩这个网络请求框架,这个由squareup公司开源的网络请求框架确实挺好用,今天我们就来看一下这个东东怎么玩! Retrofit作为 ...

  3. webstorm 编辑器破解 (麻麻再也不用担心过期了)

    先去官网下载webstorm2016.1.3版本(目前只知道2016.1这个版本可以永久破解,不会过期) 再下载webstorm2016.1的破解补丁 将下载好的破解补丁解压,会有一个Jetbrain ...

  4. 妈妈再也不用担心别人问我是否真正用过redis了

    1. Memcache与Redis的区别 1.1. 存储方式不同 1.2. 数据支持类型 1.3. 使用底层模型不同 2. Redis支持的数据类型 3. Redis的回收策略 4. Redis小命令 ...

  5. 锋利的js之妈妈再也不用担心我找错钱了

    用js实现收银功能. <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <hea ...

  6. 【阿里云产品公测】离线归档OAS,再也不用担心备份空间了

    [阿里云产品公测]离线归档OAS,再也不用担心备份空间了 作者:阿里云用户莫须有3i 1 起步  1.1 初识OAS  啥是OAS,请看官方说明: 引用: 开放归档服务(Open Archive Se ...

  7. 有了 tldr,妈妈再也不用担心我记不住命令了

    引言 有一次我在培训时说「程序员要善于使用 Terminal 以提高开发效率」,一位程序员反驳道:「这是 21 世纪,我们为什么要用落后的命令行,而不是先进的 GUI?」 是的,在一些人眼里,这个黑黑 ...

  8. 妈妈再也不用担心我使用git了

    妈妈再也不用担心我使用git了 Dec 29, 2014 git git由于其灵活,速度快,离线工作等特点而倍受青睐,下面一步步来总结下git的基本命令和常用操作. 安装msysgit 下载地址:ms ...

  9. 利用CH341A编程器刷新BIOS,恢复BIOS,妈妈再也不用担心BIOS刷坏了

    前几天,修电脑主析就捣鼓刷BIOS,结果刷完黑屏开不了机,立刻意识到完了,BIOS刷错了.就从网上查资料,各种方法试了个遍,什么用处都没有.终于功夫不负有心人,找到了编码器,知道了怎么用.下面看看具体 ...

随机推荐

  1. APP漏洞扫描器之本地拒绝服务检测详解

    APP漏洞扫描器之本地拒绝服务检测详解 阿里聚安全的Android应用漏洞扫描器有一个检测项是本地拒绝服务漏洞的检测,采用的是静态分析加动态模糊测试的方法来检测,检测结果准确全面.本文将讲一下应用漏洞 ...

  2. Code First开发系列实战之使用EF搭建小型博客平台

    返回<8天掌握EF的Code First开发>总目录 本篇目录 理解应用需求 数据库设计 创建实体数据模型 创建实体类 创建关系和导航属性 实现DbContext类 执行数据访问 理解仓储 ...

  3. 自己动手写一个简单的MVC框架(第一版)

    一.MVC概念回顾 路由(Route).控制器(Controller).行为(Action).模型(Model).视图(View) 用一句简单地话来描述以上关键点: 路由(Route)就相当于一个公司 ...

  4. Java中迭代器

    任何容器类,都必须有某种方法可以插入元素并将它们再次取回,毕竟,持有事物是容器最基本的工作,对于List,add()是出入元素的方法之一,而get()是取出元素的方法之一. 如果从更高层的角度思考,会 ...

  5. Linux更改用户密码

    登录虚拟机后,使用passwd密令更改用户密码,新密码需要输入两次才能更改成功.不多说,直接上代码 [root@localhost Desktop]# passwd //使用passwd密令 Chan ...

  6. CSS3总结 (帅哥)

    第1章CSS3简介 如同人类的的进化一样,CSS3是CSS2的"进化"版本,在CSS2基础上,增强或新增了许多特性, 弥补了CSS2的众多不足之处,使得Web开发变得更为高效和便捷 ...

  7. SSIS Design3:并发执行

    1,利用优先约束来并发处理数据,Data Flow Task 和 Data Flow Task 1 是并发执行的,而 Data Flow Task2 必须等到 Data Flow Task 和 Dat ...

  8. Sql Server系列:子查询

    1 子查询概念 子查询是嵌套在另一个查询中的普通T-SQL查询.在有一个SELECT语句通过使用小括号创建子查询,作为另一个查询的部分数据或条件的基础. 子查询通常用于满足以下某个需求: ◊ 将一个查 ...

  9. [WPF]带下拉列表的文本框

    控件我已经弄好了,代码比较多,所以没办法全面介绍. 一开始我是直接继承Selector类来实现,做是做出来了,不过发现性能不太好.于是,我就想着自己来实现.毕竟我是做给自己用的,也不考虑过多的东西,也 ...

  10. UDP(强行关闭了一个现有的连接远程主机)

    事件回顾:客户端连接服务器 ,一段时间后会发生服务器“挂掉”的情况,为了找到原因,在调试模式下运行服务器,捕捉到了一下异常: 红色框出来的即为异常原因:强行关闭了一个现有的连接远程主机 然后就发生了可 ...