国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

用設(shè)計(jì)模式開發(fā)通用數(shù)據(jù)庫操作器

2024-07-21 02:23:51
字體:
供稿:網(wǎng)友
我們都希望在開發(fā)軟件的時(shí)候能少寫一些代碼,希望能到處使用,希望不用管什么樣的數(shù)據(jù)庫軟件都能用,我們?cè)撛趺崔k呢?
我們操作數(shù)據(jù)庫時(shí)用到些什么類
一般來說,我們對(duì)數(shù)據(jù)庫進(jìn)行操作時(shí)都會(huì)用到一些類,下面我就對(duì)著些類做個(gè)總結(jié):
1. sqlserver:
a) system.data.sqlclient.sqldataadapter:sql數(shù)據(jù)適配器。表示用于填充 dataset 和更新 sql server 數(shù)據(jù)庫的一組數(shù)據(jù)命令和一個(gè)數(shù)據(jù)庫連接。無法繼承此類。該類繼承于system.data.common.dbdataadapter和實(shí)現(xiàn)接口system.data.idbdataadapter。采用adapter模式設(shè)計(jì)。
b) system.data.sqlclient.sqlconnection:sql數(shù)據(jù)庫連接。表示 sql server 數(shù)據(jù)庫的一個(gè)打開的連接。無法繼承此類。
c) system.data.sqlclient.sqlcommandbuilder:sql數(shù)據(jù)庫命令生成器。自動(dòng)生成具有以下用途的單表命令:使對(duì) dataset 所做的更改與關(guān)聯(lián)的 sql server 數(shù)據(jù)庫相協(xié)調(diào)。無法繼承此類。采用builder模式設(shè)計(jì)。
另外還有一些,但是在本文中將用不到,所以這里也就不再敘述了。
2. oracle:
a) system.data.oracleclient.oracledataadapter:oracle數(shù)據(jù)適配器。表示用于填充 dataset 和更新oracle數(shù)據(jù)庫的一組數(shù)據(jù)命令和到數(shù)據(jù)庫的連接。無法繼承此類。該類繼承于system.data.common.dbdataadapter和實(shí)現(xiàn)接口system.data.idbdataadapter。采用adapter模式設(shè)計(jì)。
b) system.data.oracleclient.oracleconnection:oracle數(shù)據(jù)庫連接。表示一個(gè)到oracle數(shù)據(jù)庫的打開的連接。無法繼承此類。
c) system.data.oracleclient.oraclecommandbuilder:oracle數(shù)據(jù)庫命令生成器。自動(dòng)生成用于協(xié)調(diào) dataset 的更改與關(guān)聯(lián)的oracle數(shù)據(jù)庫的單表命令。無法繼承此類。采用builder模式設(shè)計(jì)。
3. odbc:
a) system.data.odbc.odbcdataadapter:odbc類型數(shù)據(jù)數(shù)據(jù)適配器。表示數(shù)據(jù)命令集和到odbc數(shù)據(jù)源的連接,它們用于填充 dataset 以及更新該數(shù)據(jù)源。無法繼承此類。。該類繼承于system.data.common.dbdataadapter和實(shí)現(xiàn)接口system.data.idbdataadapter。采用adapter模式設(shè)計(jì)。
b) system.data.odbc.odbcconnection:odbc數(shù)據(jù)庫連接。表示到odbc數(shù)據(jù)源的連接是打開的。
c) system.data.odbc.odbccommandbuilder:odbc數(shù)據(jù)庫命令生成器。自動(dòng)生成用于協(xié)調(diào) dataset 的更改與關(guān)聯(lián)的odbc類型數(shù)據(jù)源的單表命令。無法繼承此類。采用builder模式設(shè)計(jì)。
4. oledb:
a) system.data.oledb.oledbdataadapter:odbc類型數(shù)據(jù)數(shù)據(jù)適配器。表示數(shù)據(jù)命令集和到oledb數(shù)據(jù)源的連接,它們用于填充 dataset 以及更新該數(shù)據(jù)源。無法繼承此類。。該類繼承于system.data.common.dbdataadapter和實(shí)現(xiàn)接口system.data.idbdataadapter。采用adapter模式設(shè)計(jì)。
b) system.data.oledb.oledbconnection:oledb數(shù)據(jù)庫連接。表示到oledb數(shù)據(jù)源的連接是打開的。
c) system.data.oledb.oledbcommandbuilder:oledb數(shù)據(jù)庫命令生成器。自動(dòng)生成用于協(xié)調(diào) dataset 的更改與關(guān)聯(lián)的oledb類型數(shù)據(jù)源的單表命令。無法繼承此類。采用builder模式設(shè)計(jì)。
我們需要什么樣的數(shù)據(jù)操作器
當(dāng)然是越簡(jiǎn)單越好了,功能倒不一定要強(qiáng)大,夠用就行。希望能支持多種數(shù)據(jù)庫,使用這個(gè)操作器的程序不用再考慮是那種數(shù)據(jù)庫;希望能對(duì)多個(gè)數(shù)據(jù)庫操作,一個(gè)項(xiàng)目使用多個(gè)數(shù)據(jù)庫卻不對(duì)增加編程復(fù)雜度;希望支持事務(wù),失敗能夠自動(dòng)回滾。功能嘛,能讀取數(shù)據(jù)、更新數(shù)據(jù)就可以了。
通用數(shù)據(jù)操作器的思路
對(duì)數(shù)據(jù)庫的操作其實(shí)就是兩件事:出和進(jìn)。出呢就是從數(shù)據(jù)庫中讀取數(shù)據(jù),進(jìn)就是將數(shù)據(jù)寫回?cái)?shù)據(jù)庫,包括新增數(shù)據(jù)、更新數(shù)據(jù)、刪除數(shù)據(jù)。
那么對(duì)這兩個(gè)件事情該怎么做呢?
讀取數(shù)據(jù)時(shí),我們是打開一個(gè)連接,實(shí)例化一個(gè)數(shù)據(jù)適配器然后填充數(shù)據(jù)集,關(guān)閉連接,即可。這里要注意的是,由于數(shù)據(jù)集里的表經(jīng)常是數(shù)據(jù)庫里多個(gè)數(shù)據(jù)表join的結(jié)果,所以你甭想讓操作器自動(dòng)生成查詢語句,得你自己寫。
寫入數(shù)據(jù)的時(shí)候,就會(huì)有一些麻煩,但因?yàn)槎际菆?zhí)行單表操作所以你可以不用自己寫sql語句,讓操作器自己生成好了。
那么一步步怎么做呢?先打開一個(gè)數(shù)據(jù)庫連接,再生成一個(gè)查詢字符串,接著這兩個(gè)東東實(shí)例化一個(gè)數(shù)據(jù)適配器,在生成一個(gè)commandbuilder的實(shí)例并注冊(cè)為dataadapter的偵聽器,接著配置事務(wù)。然后更新數(shù)據(jù)庫,最后關(guān)閉連接。事務(wù)不能更早配置,是因?yàn)榕渲玫氖聞?wù)之后便不允許數(shù)據(jù)適配器的命令為空。
思路有了,后面就很簡(jiǎn)單了,我們只需要為每一種數(shù)據(jù)庫連接定義這些操作,然后根據(jù)實(shí)際情況調(diào)用就可以了。
當(dāng)然我們不希望使用哪種數(shù)據(jù)庫的由調(diào)用它的系統(tǒng)作為參數(shù)傳入,定義在配置文件中似乎更好一些。
由于可能有多個(gè)數(shù)據(jù)庫,所以我們應(yīng)當(dāng)體現(xiàn)這種情況。比如我們可以定義默認(rèn)數(shù)據(jù)庫連接為“dbcon”,數(shù)據(jù)庫a的連接為“adbcon”。
由于要實(shí)現(xiàn)多張表的操作,所以我們要定義一個(gè)數(shù)據(jù)集表和表名的映射。
代碼實(shí)現(xiàn)
首先定義一個(gè)枚舉,以指定可以支持哪些數(shù)據(jù)庫:
/// <summary>
/// 數(shù)據(jù)庫類型枚舉
/// </summary>
public enum dbtype
{
/// <summary>
/// sqlserver
/// </summary>
sqlserver,
/// <summary>
/// oracle
/// </summary>
oracle,
/// <summary>
/// oledb
/// </summary>
oledb,
/// <summary>
/// odbc
/// </summary>
odbc
}

定義一個(gè)類來擴(kuò)展datatable:
/// <summary>
/// 用于更新數(shù)據(jù)庫的數(shù)據(jù)表、庫表名對(duì)
/// </summary>
public class datatableextend
{
/// <summary>
/// 數(shù)據(jù)表
/// </summary>
public system.data.datatable datatable;

/// <summary>
/// 數(shù)據(jù)表映射到數(shù)據(jù)庫的表名
/// </summary>
public string datatablename;

/// <summary>
/// 用于更新數(shù)據(jù)庫的數(shù)據(jù)表、庫表名對(duì)構(gòu)造函數(shù)
/// </summary>
/// <param name="mytable">用于更新數(shù)據(jù)庫的數(shù)據(jù)表</param>
/// <param name="mytablename">數(shù)據(jù)表映射到數(shù)據(jù)庫的表名</param>
public datatableextend(system.data.datatable mytable, string mytablename)
{
datatable = mytable;
datatablename = mytablename;
}
}

然后寫一個(gè)類來讀取配置文件并獲取數(shù)據(jù)庫連接字符串:
/// <summary>
/// dbsetting 的摘要說明。
/// </summary>
public class dbsetting
{
/// <summary>
/// 數(shù)據(jù)庫連接字符串后綴
/// </summary>
public static string dbconnectionends
{
get
{
return "dbcon";
}
}

/// <summary>
/// 數(shù)據(jù)庫類型后綴
/// </summary>
public static string dbtypeends
{
get
{
return "dbtype";
}
}
/// <summary>
/// 獲取指定數(shù)據(jù)庫的類型
/// </summary>
/// <param name="dbname">指定的數(shù)據(jù)庫名</param>
/// <returns>指定數(shù)據(jù)庫的類型</returns>
public static dbtype getdbtype(string dbname)
{
string dbtype = null;
dbtype = appconfig.getappsetting(dbname + dbtypeends);
if (dbtype.tolower() == dbtype.oracle.tostring().tolower())
{
return dbtype.oracle;
}
if (dbtype.tolower() == dbtype.odbc.tostring().tolower())
{
return dbtype.odbc;
}
if (dbtype.tolower() == dbtype.oledb.tostring().tolower())
{
return dbtype.oledb;
}
else
{
return dbtype.sqlserver;
}
}
/// <summary>
/// 保存指定數(shù)據(jù)庫的類型
/// </summary>
/// <param name="dbtype">指定數(shù)據(jù)庫的類型</param>
/// <param name="dbname">指定的數(shù)據(jù)庫名</param>
public static void savedbtype(dbtype dbtype,string dbname)
{
appconfig.saveappsetting(dbname + dbtypeends,dbtype.tostring());
}
/// <summary>
/// 獲取指定數(shù)據(jù)庫的連接字符串
/// </summary>
/// <param name="dbname">指定的數(shù)據(jù)庫名</param>
/// <returns>指定數(shù)據(jù)庫的連接字符串</returns>
public static string getdbconnectionstring(string dbname)
{
return appconfig.getappsetting(dbname + dbconnectionends);
}

/// <summary>
/// 保存指定數(shù)據(jù)庫的連接字符串
/// </summary>
/// <param name="connectionstring">連接字符串</param>
/// <param name="dbname">指定的數(shù)據(jù)庫名</param>
public static void savedbconnectionstring(string connectionstring, string dbname)
{
appconfig.saveappsetting(dbname + dbconnectionends,connectionstring);
}
}

接著為每一種數(shù)據(jù)庫寫一個(gè)類來執(zhí)行針對(duì)該數(shù)據(jù)庫的操作,例如針對(duì)sql server:
/// <summary>
/// 用于sql數(shù)據(jù)源操作的類
/// </summary>
public class sqlexec
{
/// <summary>
/// 獲取數(shù)據(jù)庫連接,讀取由storm.appsetting的配置文件中dbname + "dbcon"的設(shè)置(如針對(duì)數(shù)據(jù)庫test的配置鍵是“testdbcon”),若沒有,則拋出異常
/// </summary>
/// <param name="dbname">要獲取數(shù)據(jù)連接的數(shù)據(jù)庫名</param>
/// <returns>得到的數(shù)據(jù)庫連接</returns>
public static sqlconnection getdbconnection(string dbname)
{
return new sqlconnection(dbsetting.getdbconnectionstring());
}

private void modifydatabase(datatableextend[] dts, string dbname)
{
//打開連接
sqlconnection sqlcon = getdbconnection(dbname);
sqlcon.open();
//根據(jù)數(shù)據(jù)表的多少生成多個(gè)數(shù)據(jù)適配器并分別生成sql語句
int length = dts.length;
sqldataadapter[] mydataadapters = new sqldataadapter[length];
for (int i = 0; i < length; i++)
{
string selecttext = getselectcommand(dts[i].datatablename);
mydataadapters[i] = new sqldataadapter(selecttext, sqlcon);
sqlcommandbuilder cb = new sqlcommandbuilder(mydataadapters[i]);
mydataadapters[i].insertcommand = cb.getinsertcommand();
mydataadapters[i].updatecommand = cb.getupdatecommand();
mydataadapters[i].deletecommand = cb.getdeletecommand();
}
//配置事務(wù)
sqltransaction mytrans;
mytrans = sqlcon.begintransaction(isolationlevel.repeatableread);
try
{
for (int i = 0; i < length; i++)
{
mydataadapters[i].selectcommand.transaction = mytrans;
mydataadapters[i].insertcommand.transaction = mytrans;
mydataadapters[i].updatecommand.transaction = mytrans;
mydataadapters[i].deletecommand.transaction = mytrans;
//更新數(shù)據(jù)庫
mydataadapters[i].update(dts[i].datatable);
}
mytrans.commit();
sqlcon.close();
for(int i = 0; i < length ; i++)
{
dts[i].datatable.acceptchanges();
}
}
//如果失敗,則自動(dòng)回滾
catch(exception ee)
{
mytrans.rollback();
sqlcon.close();
for(int i = 0; i < length ; i++)
{
dts[i].datatable.rejectchanges();
}
throw ee;
}
}

/// <summary>
/// 從數(shù)據(jù)庫中讀取數(shù)據(jù)
/// </summary>
/// <param name="dt">要承載數(shù)據(jù)的數(shù)據(jù)表</param>
/// <param name="selectstring">查詢語句</param>
public void getdata(datatable dt, string selectstring, string dbname)
{
sqldataadapter mydataadapter = new sqldataadapter(selectstring,sqlconfig.getdbconnection(dbname));
mydataadapter.fill(dt);
}

//自動(dòng)生成查詢語句
private static string getselectcommand(string datatablename)
{
string strget = "select * from " +datatablename;
return strget;
}
}

然后就是寫一個(gè)類來根據(jù)實(shí)際情況調(diào)用這些東東了:
public class databaseexecute
{
private string dbname;
/// <summary>
/// 目標(biāo)數(shù)據(jù)庫
/// </summary>
public string dbname
{
get{ return dbname; }
set{ dbname = value; }
}

/// <summary>
/// 生成databaseexecute的實(shí)例
/// </summary>
public databaseexecute()
{
dbname = null;
}

/// <summary>
/// 用指定的目標(biāo)數(shù)據(jù)庫生成databasemodifier的實(shí)例
/// </summary>
/// <param name="dbname"></param>
public databaseexecute(string dbname)
{
this.dbname = dbname;
}
/// <summary>
/// 從數(shù)據(jù)庫中讀取數(shù)據(jù)
/// </summary>
/// <param name="dt">要承載數(shù)據(jù)的數(shù)據(jù)表</param>
/// <param name="selectstring">查詢語句</param>
public void getdata(datatable dt, string selectstring)
{
//操作指定數(shù)據(jù)庫
if (dbname != null)
{
if (dbsetting.getdbtype(dbname) == dbtype.sqlserver)
{
sqlexec mysqlexec = new sqlexec();
mysqlexec. getdata(dt, selectstring, dbname);
}
else if (dbsetting.getdbtype(dbname) == dbtype.odbc)
{
odbcexec myodbcexec = new odbcexec();
myodbcexec. getdata(dt, selectstring, dbname);
}
else if (dbsetting.getdbtype(dbname) == dbtype.oledb)
{
oledbexec myoledbexec = new oledbexec();
mysqlexec. getdata(dt, selectstring, dbname);
}
else
{
oracleexec myoracleexec = new oracleexec();
myoracleexec. getdata(dt, selectstring, dbname);
}
}
//操作默認(rèn)數(shù)據(jù)庫
else
{
if (dbsetting.getdbtype(“”) == dbtype.sqlserver)
{
sqlexec mysqlexec = new sqlexec();
mysqlexec. getdata(dt, selectstring, “”);
}
else if (dbsetting.getdbtype(“”) == dbtype.odbc)
{
odbcexec myodbcexec = new odbcexec();
myodbcexec. getdata(dt, selectstring, “”);
}
else if (dbsetting.getdbtype(dbname) == dbtype.oledb)
{
oledbexec myoledbexec = new oledbexec();
mysqlexec. getdata(dt, selectstring, “”);
}
else
{
oracleexec myoracleexec = new oracleexec();
myoracleexec. getdata(dt, selectstring, “”);
}
}
}

/// <summary>
/// 根據(jù)數(shù)據(jù)表組更新數(shù)據(jù)庫
/// </summary>
/// <param name="dts">要更新的數(shù)據(jù)表組</param>
public void modifydatabase(datatableextend[] dts)
{
//操作指定數(shù)據(jù)庫
if (dbname != null)
{
if (dbsetting.getdbtype(dbname) == dbtype.sqlserver)
{
sqlexec mysqlexec = new sqlexec();
mysqlexec modifydatabase(dts,dbname);
}
else if (dbsetting.getdbtype(dbname) == dbtype.odbc)
{
odbcexec mysqlexec = new odbcexec();
myodbcexec modifydatabase(dts,dbname);
}
else if (dbsetting.getdbtype(dbname) == dbtype.oledb)
{
oledbexec mysqlexec = new oledbexec();
myoledbexec modifydatabase(dts,dbname);
}
else
{
oracleexec mysqlexec = new oracleexec();
myoracleexec modifydatabase(dts,dbname);
}
}
//操作默認(rèn)數(shù)據(jù)庫
else
{
if (dbsetting.getdbtype(“”) == dbtype.sqlserver)
{
sqlexec mysqlexec = new sqlexec();
mysqlexec modifydatabase(dts, “”);
}
else if (dbsetting.getdbtype(dbname) == dbtype.odbc)
{
odbcexec mysqlexec = new odbcexec();
myodbcexec modifydatabase(dts, “”);
}
else if (dbsetting.getdbtype(dbname) == dbtype.oledb)
{
oledbexec mysqlexec = new oledbexec();
myoledbexec modifydatabase(dts, “”);
}
else
{
oracleexec mysqlexec = new oracleexec();
myoracleexec modifydatabase(dts, “”);
}
}
}

這樣,在項(xiàng)目中只要引用這個(gè)databaseexecute類就可以了。
最后,要注意的幾點(diǎn):
1. 對(duì)于多表操作而言,因?yàn)楸黹g有關(guān)聯(lián),所以操作的順序很重要,本構(gòu)件操作的順序是從數(shù)據(jù)表數(shù)組的前向后處理,請(qǐng)千萬注意表處理的順序!
2. 默認(rèn)數(shù)據(jù)庫連接由配置文件中“dbcon”的設(shè)置決定,非默認(rèn)數(shù)據(jù)庫連接由配置文件中“*dbcon”的設(shè)置決定,其中星號(hào)代表數(shù)據(jù)庫標(biāo)識(shí)
3. 默認(rèn)數(shù)據(jù)庫類型由配置文件中“dbcon”的設(shè)置決定,非默認(rèn)數(shù)據(jù)庫類型由配置文件中“*dbcon”的設(shè)置決定,其中星號(hào)代表數(shù)據(jù)庫標(biāo)識(shí)
4. 針對(duì)每一個(gè)數(shù)據(jù)庫都有兩個(gè)配置,分別是數(shù)據(jù)庫連接和數(shù)據(jù)庫類型。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 武川县| 乌拉特中旗| 嘉鱼县| 尉犁县| 红原县| 万源市| 布拖县| 德清县| 奉化市| 普洱| 长葛市| 肥乡县| 曲周县| 乐平市| 六枝特区| 达州市| 北宁市| 富阳市| 栾城县| 城口县| 金秀| 大悟县| 秦安县| 松溪县| 会理县| 志丹县| 分宜县| 宝丰县| 远安县| 南澳县| 沅江市| 宾阳县| 宁安市| 大同市| 汝城县| 逊克县| 和平县| 齐河县| 修文县| 辉县市| 辉南县|