虽然现在有很多ORM ,但有时候我们可能只是需要简单的数据操作,于是写了一个数据库通用访问组件。其实这个最开始连接口都没有,到最后逐步完善.虽然是普通的数据访问,但是我们还是要来实现一些可插拔特性和工厂模式.
首先来定义接口
using System;
using System.Collections.Generic;
using System.Data;
using System.Collections;
using System.Data.Common;
namespace FYJ.Data
{
public enum DbHelperType : int
{
Other = 0,
SqlServer = 1,
Oracle = 2,
OleDb = 3,
MySql = 4,
SqlLite = 5,
Odbc = 6
}
////// 功能:数据接口
/// 作者:fangyj
/// 创建日期:2012-07-15
/// 修改日期:2013-08-11
///public interface IDbHelper
{
#region 执行
////// 执行一条sql语句
////////////int ExecuteSql(string sql, params IDataParameter[] parms);
////// 执行一条sql语句
////////////int ExecuteSql(IEnumerableparms, string sql);
////// 根据IDataParameter 自动生成sql语句并执行
//////表明///主键名///是否插入语句,否则为修改//////int ExecuteSql(string tableName, string pkName, bool iaAdd, IEnumerableparms);
////// 执行存储过程 返回DataSet
//////存储过程参数///存储过程名///DataSet RunProcedure(IEnumerableparms, string storedProcName);
////// 执行存储过程 返回DataSet
//////存储过程名///存储过程参数///DataSet RunProcedure(string storedProcName, params IDataParameter[] parms);
////// 执行存储过程
//////存储过程名///以存储过程参数名为key 参数值为value///DataSet RunProcedure(string storedProcName, Dictionary dic);
////// 执行存储过程 返回整数值 @RETURN_VALUE
////////////int ExecuteProcedure(string storedProcName, Dictionary dic);
////// 执行存储过程 返回整数值 @RETURN_VALUE
////////////int ExecuteProcedure(IEnumerableparms, string storedProcName);
////// 执行存储过程 返回整数值 @RETURN_VALUE
////////////int ExecuteProcedure(string storedProcName, params IDataParameter[] parms);
#endregion
#region 查询
////// 获取DataSet
////////////DataSet GetDataSet(IEnumerableparms, string sql);
////// 获取DataSet
////////////DataSet GetDataSet(string sql, params IDataParameter[] parms);
////// 获取查询的数据列表 IDataParameter参数前缀@ :或者不加都会自动修正 currentPage设置为0表示不返回数据 currentPage为null则返回所有数据
/// count传递null表示不返回总数
//////是否返回总记录条数///表或视图名///要访问的列///查询条件///排序///当前页///每页显示条数///DataTable GetDataTable(ref long? count, string tableName, string order, string[] accessProperty = null, string where = null, int currentPage = 1, int pageSize = 20);
////// 获取DataTable 该值为DataSet的第一张表
////////////DataTable GetDataTable(IEnumerableparms, string sql);
////// 获取DataTable 该值为DataSet的第一张表
////////////DataTable GetDataTable(string sql, params IDataParameter[] parms);
////// 获取前max行数据 如果max小于1 则返回所有行
//////表名//////DataTable GetDataTable(string tableName, long max);
////// 获取第一行第一列object值
////////////object GetObject(IEnumerableparms, string sql);
object GetObject(string sql, params IDataParameter[] parms);
string GetString(IEnumerableparms, string sql);
string GetString(string sql, params IDataParameter[] parms);
long GetLong(IEnumerableparms, string sql);
long GetLong(string sql, params IDataParameter[] parms);
double GetDouble(IEnumerableparms, string sql);
double GetDouble(string sql, params IDataParameter[] parms);
int GetInt(IEnumerableparms, string sql);
int GetInt(string sql, params IDataParameter[] parms);
bool GetBoolean(IEnumerableparms, string sql);
bool GetBoolean(string sql, params IDataParameter[] parms);
bool Exists(IEnumerableparms, string sql);
bool Exists(string sql, params IDataParameter[] parms);
////// 表是否存在
/////////bool ExistsTable(string tableName);
////// 获取当前数据库所有表
//////ListGetTables();
#endregion
////// 创建DbParameter对象
///////////////DbParameter CreateParameter(string parameterName = null, object parameterValue = null, ParameterDirection? direction = null);
#region 属性
////// 获取DbProviderFactory对象
//////DbProviderFactory DbProviderFactoryInstance { get; set; }
////// 获取连接对象
//////DbConnection DbConnectionInstance { get; set; }
////// 获取数据类型枚举
//////DbHelperType DbHelperTypeEnum { get; }
DbTransaction Tran { get; }
#endregion
////// 开始事务
///void BeginTran();
////// 提交事务
///void Commit();
////// 回滚
///void Rollback();
////// 打开连接
///void OpenConnection();
////// 关闭连接
///void CloseConnection();
////// 测试数据库是否可以打开
//////bool TestCanConnectionOpen();
}
}
这个接口是不是有点多。。。
我们没有使用config文件里面的appSettings和connectionStrings来配置,因为需要扩展更多的属性.于是自己写section吧,当然也可以自己写xml,感觉写xml还简单些
以下是配置文件
可以看到有很多属性,name是唯一的id不能重复,type是FYJ.Data.IDbHelper接口的实现,isEncrypt表示是否加密连接字符串,encryptType是实现了FYJ.Data.IDbEncrypt的解密类,该接口就只有一个方法 string Decrypt(string text);返回解密后的字符串
下面我们来看工厂类
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Data.Common;
using System.Configuration;
using System.Text.RegularExpressions;
using System.IO;
namespace FYJ.Data
{
////// 工厂类,无法继承该类
///public sealed class DbFactory
{
private static Dictionary dbs = new Dictionary();
////// 根据配置节点主键名构造IDbHelper对象
/////////public static IDbHelper CreateIDbHelper(string configName)
{
var items = (ConfigurationManager.GetSection("DbHelperSettings") as FYJ.Data.Config.DbHelperSection).Items;
foreach (FYJ.Data.Config.DbHelperElement item in items)
{
if (item.Name == configName)
{
Type t = Type.GetType(item.Type);
IDbHelper db = (IDbHelper)Activator.CreateInstance(t);
DbProviderFactory factory = null;
string connectionString = item.ConnectionString;
if (item.IsEncrypt == true)
{
IDbEncrypt encrypt = (IDbEncrypt)Activator.CreateInstance(Type.GetType(item.EncryptType));
connectionString = encrypt.Decrypt(connectionString);
}
if (item.ProviderName.StartsWith("MySql.Data", StringComparison.CurrentCultureIgnoreCase))
{
object obj = Assembly.Load("MySql.Data").CreateInstance("MySql.Data.MySqlClient.MySqlClientFactory");
factory = (DbProviderFactory)obj;
}
else if (item.ProviderName.StartsWith("System.Data.SQLite", StringComparison.CurrentCultureIgnoreCase))
{
object obj = Assembly.Load("System.Data.SQLite").CreateInstance("System.Data.SQLite.SQLiteFactory");
factory = (DbProviderFactory)obj;
String dbFileName = Regex.Match(connectionString, "data\\s*source\\s*=\\s*(.*)").Groups[1].Value;
if (!File.Exists(dbFileName))
{
connectionString = "data source=" + Path.Combine(AppDomain.CurrentDomain.BaseDirectory, dbFileName);
}
}
else
{
factory = DbProviderFactories.GetFactory(item.ProviderName);
}
db.DbProviderFactoryInstance = factory;
db.DbConnectionInstance = factory.CreateConnection();
db.DbConnectionInstance.ConnectionString = connectionString;
return db;
}
}
throw new Exception("名为" + configName + "的数据配置不存在");
}
////// 根据配置节点主键名构造IDbHelper对象
/////////public static IDbHelper GetIDbHelper(string configName)
{
if (!dbs.ContainsKey(configName))
{
dbs.Add(configName, CreateIDbHelper(configName));
}
return dbs[configName];
}
}
}
CreateIDbHelper 方法是创建一个实现FYJ.Data.IDbHelper接口的实例,相应GetIDbHelper方法是得到一个静态的全局实例,并且会自动修正SQLite的连接字符串
由于代码贴得有点多,所以留在下面一篇
珂珂的个人博客 - 一个程序猿的个人网站