本示例代碼的關(guān)鍵是利用.net庫(kù)自帶的DbProviderFactory來(lái)生產(chǎn)數(shù)據(jù)庫(kù)操作對(duì)象。
從下圖中,可以看到其的多個(gè)核心方法,這些方法將在我們的超級(jí)DBHelper中使用。


仔細(xì)研究,你會(huì)發(fā)現(xiàn)每個(gè)數(shù)據(jù)庫(kù)的官方支持dll都有一個(gè)Instance對(duì)象,這個(gè)對(duì)象都是繼承了DbProviderFactory了。
因此利用這點(diǎn),我們就可以實(shí)現(xiàn)兼容多種數(shù)據(jù)的超級(jí)DBHelper了。
以下為示例代碼,僅供參考學(xué)習(xí),代碼只是我的ORM框架中的一個(gè)片段(其中暫時(shí)支持了SQLSERVER、MYSQL、SQLITE三種數(shù)據(jù)庫(kù),LoadDbProviderFactory方法是將封裝在dll中的數(shù)據(jù)庫(kù)操作dll反射加載實(shí)例化的方法。):
-
/// <summary>
-
/// 超級(jí)數(shù)據(jù)庫(kù)操作類
-
/// <para>2015年12月21日</para>
-
/// <para>v1.0</para>
-
/// <para>葉琪</para>
-
/// </summary>
-
public class DBHelper
-
{
-
#region 屬性
-
private DbProviderFactory _DbFactory;
-
private DBConfig mDBConfig;
-
-
/// <summary>
-
/// 數(shù)據(jù)庫(kù)連接配置
-
/// </summary>
-
public DBConfig DBConfig
-
{
-
get { return mDBConfig; }
-
}
-
-
/// <summary>
-
/// 表示一組方法,這些方法用于創(chuàng)建提供程序?qū)?shù)據(jù)源類的實(shí)現(xiàn)的實(shí)例。
-
/// </summary>
-
public DbProviderFactory DbFactory
-
{
-
get { return _DbFactory; }
-
set { _DbFactory = value; }
-
}
-
#endregion
-
-
#region 構(gòu)造函數(shù)
-
public DBHelper(DBConfig aORMConfig)
-
{
-
mDBConfig = aORMConfig;
-
switch (mDBConfig.DBType)
-
{
-
case ORMType.DBTypes.SQLSERVER:
-
_DbFactory = System.Data.SqlClient.SqlClientFactory.Instance;
-
break;
-
case ORMType.DBTypes.MYSQL:
-
LoadDbProviderFactory("MySql.Data.dll", "MySql.Data.MySqlClient.MySqlClientFactory");
-
break;
-
case ORMType.DBTypes.SQLITE:
-
LoadDbProviderFactory("System.Data.SQLite.dll", "System.Data.SQLite.SQLiteFactory");
-
break;
-
}
-
}
-
-
/// <summary>
-
/// 動(dòng)態(tài)載入數(shù)據(jù)庫(kù)封裝庫(kù)
-
/// </summary>
-
/// <param name="aDLLName">數(shù)據(jù)庫(kù)封裝庫(kù)文件名稱</param>
-
/// <param name="aFactoryName">工廠路徑名稱</param>
-
private void LoadDbProviderFactory(string aDLLName, string aFactoryName)
-
{
-
string dllPath = string.Empty;
-
if (System.AppDomain.CurrentDomain.RelativeSearchPath != null)
-
{
-
dllPath = System.AppDomain.CurrentDomain.RelativeSearchPath+"\\"+ aDLLName;
-
}
-
else
-
{
-
dllPath = System.AppDomain.CurrentDomain.BaseDirectory + aDLLName;
-
}
-
if (!File.Exists(dllPath))
-
{//文件不存在,從庫(kù)資源中復(fù)制輸出到基目錄下
-
FileStream fdllFile = new FileStream(dllPath,FileMode.Create);
-
byte[] dllData = null;
-
if (aDLLName == "System.Data.SQLite.dll")
-
{
-
dllData = YFmk.ORM.Properties.Resources.System_Data_SQLite;
-
}
-
else if (aDLLName == "MySql.Data.dll")
-
{
-
dllData = YFmk.ORM.Properties.Resources.MySql_Data;
-
}
-
fdllFile.Write(dllData, 0, dllData.Length);
-
fdllFile.Close();
-
}
-
Assembly libAssembly = Assembly.LoadFile(dllPath);
-
Type type = libAssembly.GetType(aFactoryName);
-
foreach (FieldInfo fi in type.GetFields(BindingFlags.Static | BindingFlags.Public))
-
{
-
if (fi.Name == "Instance")
-
{
-
_DbFactory = fi.GetValue(null) as DbProviderFactory;
-
return;
-
}
-
}
-
}
-
#endregion
-
-
#region 數(shù)據(jù)庫(kù)操作
-
/// <summary>
-
/// 執(zhí)行一條計(jì)算查詢結(jié)果語(yǔ)句,返回查詢結(jié)果
-
/// </summary>
-
/// <param name="aSQLWithParameter">SQL語(yǔ)句及參數(shù)</param>
-
/// <returns>查詢結(jié)果(object)</returns>
-
public object GetSingle(SQLWithParameter aSQLWithParameter)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
using (DbCommand cmd = _DbFactory.CreateCommand())
-
{
-
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
-
object obj = cmd.ExecuteScalar();
-
cmd.Parameters.Clear();
-
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
-
{
-
return null;
-
}
-
else
-
{
-
return obj;
-
}
-
}
-
}
-
}
-
-
/// <summary>
-
/// 執(zhí)行SQL語(yǔ)句,返回影響的記錄數(shù)
-
/// </summary>
-
/// <param name="aSQL">SQL語(yǔ)句</param>
-
/// <returns>影響的記錄數(shù)</returns>
-
public int ExecuteSql(string aSQL)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
using (DbCommand cmd = _DbFactory.CreateCommand())
-
{
-
PrepareCommand(cmd, conn, aSQL);
-
int rows = cmd.ExecuteNonQuery();
-
cmd.Parameters.Clear();
-
return rows;
-
}
-
}
-
}
-
-
/// <summary>
-
/// 執(zhí)行SQL語(yǔ)句,返回影響的記錄數(shù)
-
/// </summary>
-
/// <param name="aSQLWithParameter">SQL語(yǔ)句及參數(shù)</param>
-
/// <returns></returns>
-
public int ExecuteSql(SQLWithParameter aSQLWithParameter)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
using (DbCommand cmd = _DbFactory.CreateCommand())
-
{
-
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
-
int rows = cmd.ExecuteNonQuery();
-
cmd.Parameters.Clear();
-
return rows;
-
}
-
}
-
}
-
-
/// <summary>
-
/// 執(zhí)行多條SQL語(yǔ)句,實(shí)現(xiàn)數(shù)據(jù)庫(kù)事務(wù)。
-
/// </summary>
-
/// <param name="aSQLWithParameterList">參數(shù)化的SQL語(yǔ)句結(jié)構(gòu)體對(duì)象集合</param>
-
public string ExecuteSqlTran(List<SQLWithParameter> aSQLWithParameterList)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
conn.Open();
-
DbTransaction fSqlTransaction = conn.BeginTransaction();
-
try
-
{
-
List<DbCommand> fTranCmdList = new List<DbCommand>();
-
//創(chuàng)建新的CMD
-
DbCommand fFirstCMD = _DbFactory.CreateCommand();
-
fFirstCMD.Connection = conn;
-
fFirstCMD.Transaction = fSqlTransaction;
-
fTranCmdList.Add(fFirstCMD);
-
int NowCmdIndex = 0;//當(dāng)前執(zhí)行的CMD索引值
-
int ExecuteCount = 0;//已經(jīng)執(zhí)行的CMD次數(shù)
-
StringBuilder fSQL = new StringBuilder();
-
foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
-
{
-
fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
-
fTranCmdList[NowCmdIndex].Parameters.AddRange(fSQLWithParameter.Parameters.ToArray());
-
if (fTranCmdList[NowCmdIndex].Parameters.Count > 2000)
-
{ //參數(shù)達(dá)到2000個(gè),執(zhí)行一次CMD
-
fTranCmdList[NowCmdIndex].CommandText = fSQL.ToString();
-
fTranCmdList[NowCmdIndex].ExecuteNonQuery();
-
DbCommand fNewCMD = _DbFactory.CreateCommand();
-
fNewCMD.Connection = conn;
-
fNewCMD.Transaction = fSqlTransaction;
-
fTranCmdList.Add(fNewCMD);
-
NowCmdIndex++;
-
ExecuteCount++;
-
fSQL.Clear();//清空SQL
-
}
-
}
-
if (ExecuteCount < fTranCmdList.Count)
-
{//已執(zhí)行CMD次數(shù)小于總CMD數(shù),執(zhí)行最后一條CMD
-
fTranCmdList[fTranCmdList.Count - 1].CommandText = fSQL.ToString();
-
fTranCmdList[fTranCmdList.Count - 1].ExecuteNonQuery();
-
}
-
fSqlTransaction.Commit();
-
return null;
-
}
-
catch (Exception ex)
-
{
-
fSqlTransaction.Rollback();
-
StringBuilder fSQL = new StringBuilder();
-
foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
-
{
-
fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
-
}
-
YFmk.Lib.LocalLog.WriteByDate(fSQL.ToString()+" 錯(cuò)誤:"+ex.Message, "ORM");
-
return ex.Message;
-
}
-
}
-
}
-
-
/// <summary>
-
/// 執(zhí)行查詢語(yǔ)句,返回DataSet
-
/// </summary>
-
/// <param name="SQLString">查詢語(yǔ)句</param>
-
/// <returns>DataSet</returns>
-
public DataSet Query(string SQLString)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
using (DbCommand cmd = _DbFactory.CreateCommand())
-
{
-
PrepareCommand(cmd, conn, SQLString);
-
using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
-
{
-
da.SelectCommand = cmd;
-
DataSet ds = new DataSet();
-
try
-
{
-
da.Fill(ds, "ds");
-
cmd.Parameters.Clear();
-
}
-
catch (Exception ex)
-
{
-
-
}
-
return ds;
-
}
-
}
-
}
-
}
-
-
/// <summary>
-
/// 執(zhí)行查詢語(yǔ)句,返回DataSet
-
/// </summary>
-
/// <param name="aSQLWithParameter">查詢語(yǔ)句</param>
-
/// <returns>DataSet</returns>
-
public DataSet Query(SQLWithParameter aSQLWithParameter)
-
{
-
using (DbConnection conn = _DbFactory.CreateConnection())
-
{
-
conn.ConnectionString = mDBConfig.ConnString;
-
using (DbCommand cmd = _DbFactory.CreateCommand())
-
{
-
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
-
using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
-
{
-
da.SelectCommand = cmd;
-
DataSet ds = new DataSet();
-
da.Fill(ds, "ds");
-
cmd.Parameters.Clear();
-
return ds;
-
}
-
}
-
}
-
}
-
#endregion
-
-
#region 私有函數(shù)
-
private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText)
-
{
-
if (conn.State != ConnectionState.Open)
-
conn.Open();
-
cmd.Connection = conn;
-
cmd.CommandText = cmdText;
-
}
-
-
private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText, List<DbParameter> cmdParms)
-
{
-
if (conn.State != ConnectionState.Open)
-
conn.Open();
-
cmd.Connection = conn;
-
cmd.CommandText = cmdText;
-
if (cmdParms != null && cmdParms.Count>0)
-
{
-
cmd.Parameters.AddRange(cmdParms.ToArray());
-
}
-
}
-
#endregion
|