虽然现在有很多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, Dictionarydic); ////// 执行存储过程 返回整数值 @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 Dictionarydbs = 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的连接字符串
由于代码贴得有点多,所以留在下面一篇