由于一個客戶朋友的需求,需要我的Winform開發(fā)框架支持國產(chǎn)達夢數(shù)據(jù)庫的操作,這個數(shù)據(jù)庫很早就聽過,但是真正一般項目用的很少,一般在一些特殊的項目可能需要用到。由于我的Winform開發(fā)框架,是基于Enterprise Library的數(shù)據(jù)訪問層的實現(xiàn),因此增加一個數(shù)據(jù)庫的支持很容易,本文介紹如何在框架層面上支持這種神秘的國產(chǎn)數(shù)據(jù)庫-達夢數(shù)據(jù)庫。
1、達夢數(shù)據(jù)庫的簡單介紹
達夢數(shù)據(jù)庫管理系統(tǒng)是達夢公司推出的具有完全自主知識產(chǎn)權(quán)的高性能數(shù)據(jù)庫管理系統(tǒng),簡稱DM。達夢數(shù)據(jù)庫管理系統(tǒng)的最新版本是7.0版本,簡稱DM7。DM7提供對SQL92的特性支持以及SQL99的核心級別支持;支持多種數(shù)據(jù)庫開發(fā)接口,包括OLE DB、ADO、ODBC、OCI、JDBC、Hibernate、PHP、PDO、DB Express以及.Net DataProvider等。
達夢數(shù)據(jù)庫可以在(http://www.dameng.com/)
上下載試用,安裝好后提供很多管理工具,安裝后可以讓它創(chuàng)建一些實例數(shù)據(jù)庫,以方便我們了解數(shù)據(jù)庫的基本操作,本人對這款數(shù)據(jù)庫了解不多,不過它號稱支持SQL-92標準的,那么使用起來就不會有什么問題的,只是一些個性化的語法需要查詢即可。
達夢數(shù)據(jù)庫的分析器,可以在上面執(zhí)行自己的一些語句,注意它的數(shù)據(jù)庫表必須帶上一個模式前綴,類似SqlServer的dbo,不過這個是必須的。
2、基于Enterprise Library的Winform開發(fā)框架的架構(gòu)支持處理
我的這款基于Enterprise Library的開發(fā)框架,底層使用了微軟的數(shù)據(jù)訪問組件Enterprise Library,以適應(yīng)多種數(shù)據(jù)庫類型的操作,它的分層如下所示,每個DAL層(如DALSQL、DALOracle等)都提供了對應(yīng)數(shù)據(jù)庫的實現(xiàn),界面層一下的分層圖如下所示。
如果增加多一種數(shù)據(jù)庫,那么我們增加多一個Enterprise Library的組件擴展類,并在業(yè)務(wù)數(shù)據(jù)模塊里面增加對應(yīng)的DAL層即可。
對于具體的DALSQL這樣的數(shù)據(jù)實現(xiàn)層,我們不需要把數(shù)據(jù)訪問的處理操作在全部的類里面實現(xiàn)一遍,我們可以通過抽象類的方式,把常規(guī)的數(shù)據(jù)庫處理操作抽象到基類上面,如下所示。
這樣在BaseDALSQL層(SqlServer數(shù)據(jù)庫的個性化實現(xiàn)部分),只需要實現(xiàn)部分功能即可,我們把大多數(shù)的數(shù)據(jù)庫操作,放到最頂級的數(shù)據(jù)庫訪問基類AbstractBaseDAL類上,從而是我們能夠盡可能減少增加不同數(shù)據(jù)庫類型,需要改寫代碼的數(shù)量。
最終我們增量增加一個數(shù)據(jù)訪問層就可以實現(xiàn)了另外一種數(shù)據(jù)庫(達夢數(shù)據(jù)庫)的實現(xiàn)了,具體的架構(gòu)設(shè)計圖如下所示。
3、具體接入測試案例代碼
上面小節(jié),我們論證了框架的可擴展性,并且理論上已經(jīng)具備支持達夢數(shù)據(jù)庫的擴張了,本小節(jié)介紹如何具體實現(xiàn)達夢數(shù)據(jù)庫的底層接入操作,并編寫一個簡單的測試例子進行測試,印證我們的實現(xiàn)思路。
我們知道,Enterprise Library實現(xiàn)其他數(shù)據(jù)庫的支持,需要增加一個組件擴展類,如EntLibContrib.Data.SQLite是用來支持SQLite數(shù)據(jù)庫的,EntLibContrib.Data.MySql是用來支持Mysql的,這個擴展類的內(nèi)容也不多,主要是用來解析如下的配置文件的.
以便能夠和Enterprise Library的對象進行無縫的整合,那么我們可以參考MySql數(shù)據(jù)庫的擴展類EntLibContrib.Data.MySql的做法,來創(chuàng)建一個基于國產(chǎn)達夢數(shù)據(jù)庫的Enterprise Library擴展類,大概項目代碼如下所示。
這樣我們就可以增加配置文件如下所示,它就能正常的解析并處理了。
下面我們來編寫測試的代碼來印證我們的擴展類,實現(xiàn)Winform開發(fā)框架支持國產(chǎn)達夢數(shù)據(jù)庫的擴展操作。
我們創(chuàng)建一個數(shù)據(jù)庫通用操作的輔助類來進行講解,代碼如下所示。
/// <summary>
/// 基于Enterprise Library類庫的數(shù)據(jù)訪問測試
/// </summary>
public class EntLibDmHelper
{
public EntLibDmHelper()
{
}
/// <summary>
/// 執(zhí)行SQL查詢語句,返回查詢結(jié)果的所有記錄的第一個字段,用逗號分隔。
/// </summary>
/// <param name="sql">SQL語句</param>
/// <returns>
/// 返回查詢結(jié)果的所有記錄的第一個字段,用逗號分隔。
/// </returns>
public string SqlValueList(string sql)
{
Database db = DatabaseFactory.CreateDatabase();
DbCommand command = db.GetSqlStringCommand(sql);
StringBuilder result = new StringBuilder();
using (IDataReader dr = db.ExecuteReader(command))
{
while (dr.Read())
{
result.AppendFormat("{0},", dr[0].ToString());
}
}
string strResult = result.ToString().Trim(',');
return strResult;
}
/// <summary>
/// 執(zhí)行SQL查詢語句,返回所有記錄的DataTable集合。
/// </summary>
/// <param name="sql">SQL查詢語句</param>
/// <returns></returns>
public DataTable SqlTable(string sql)
{
DataSet ds = new DataSet();
Database db = DatabaseFactory.CreateDatabase();
DbCommand command = db.GetSqlStringCommand(sql);
return db.ExecuteDataSet(command).Tables[0];
}
}
注意,上面的代碼沒有用到達夢的具體對象,而是使用了Enterprise Library的Database等對象來操作,這樣也就是非常方便我們進行接口的抽象處理,可以把更多的功能放到數(shù)據(jù)庫訪問抽象類里面了。
如果是利用達夢的.NET Provider的對象處理數(shù)據(jù)庫,那么具體的代碼應(yīng)該是這樣的。
/// <summary>
/// 執(zhí)行SQL查詢語句,返回查詢結(jié)果的所有記錄的第一個字段,用逗號分隔。
/// </summary>
/// <param name="sql">SQL語句</param>
/// <returns>
/// 返回查詢結(jié)果的所有記錄的第一個字段,用逗號分隔。
/// </returns>
public string SqlValueList(string sql)
{
DmConnection connection = new DmConnection(ConnectionString);
DmCommand cmd = new DmCommand(sql, connection);
connection.Open();
StringBuilder result = new StringBuilder();
using (DmDataReader dr = cmd.ExecuteReader())
{
while (dr.Read())
{
result.AppendFormat("{0},", dr[0].ToString());
}
}
string strResult = result.ToString().Trim(',');
return strResult;
}
/// <summary>
/// 執(zhí)行SQL查詢語句,返回所有記錄的DataTable集合。
/// </summary>
/// <param name="sql">SQL查詢語句</param>
/// <returns></returns>
public DataTable SqlTable(string sql)
{
DataSet ds = new DataSet();
DmDataAdapter adpater = new DmDataAdapter(sql, ConnectionString);
adpater.Fill(ds);
return ds.Tables[0];
}
為了方便測試,我編寫一個簡單的查詢例子來進行介紹,如下代碼所示,這里我們主要利用了EntLibDmHelper這個輔助類對象,也就是基于Enterprise Library的擴展的處理操作。
private void btnSearch_Click(object sender, EventArgs e)
{
BindData();
}
private void BindData()
{
string condition = "1=1 ";
if (this.txtAuthor.Text.Length > 0)
{
condition += string.Format("AND Author like '%{0}%' ", this.txtAuthor.Text);
}
if (this.txtName.Text.Length > 0)
{
condition += string.Format("AND Name like '%{0}%' ", this.txtName.Text);
}
if (this.txtPublisher.Text.Length > 0)
{
condition += string.Format("AND Publisher like '%{0}%' ", this.txtPublisher.Text);
}
string sql = "Select * from PRODUCTION.Product Where " + condition;
EntLibDmHelper helper = new EntLibDmHelper();
//DMHelper helper = new DMHelper();
DataTable dt = helper.SqlTable(sql);
this.dataGridView1.DataSource = dt;
sql = "Select count(*) from PRODUCTION.Product Where " + condition;
string totalCount = helper.SqlValueList(sql);
this.lblCount.Text = string.Format("共有數(shù)據(jù):{0}條", totalCount);
}
最后例子運行的界面效果如下所示。
基本上印證了我們對框架的整合,實現(xiàn)了支持國產(chǎn)達夢數(shù)據(jù)庫的擴展操作。剩下的就是我們模仿著把BaseDALSQL這樣的基類,為達夢數(shù)據(jù)庫增加一個個性化的數(shù)據(jù)庫處理接口,就可以實現(xiàn)整體性框架的支持了。對于各個模塊 的數(shù)據(jù)訪問,我們需要增加一個DALDM這樣的實現(xiàn)層,基類指向BaseDALDM這樣就可以了。