欢迎光临
我们一直在努力

用设计模式开发通用数据库操作器-.NET教程,数据库应用

建站超值云服务器,限时71元/月

我们都希望在开发软件的时候能少写一些代码,希望能到处使用,希望不用管什么样的数据库软件都能用,我们该怎么办呢?

我们操作数据库时用到些什么类

一般来说,我们对数据库进行操作时都会用到一些类,下面我就对着些类做个总结:

1. sqlserver:

a) system.data.sqlclient.sqldataadapter:sql数据适配器。表示用于填充 dataset 和更新 sql server 数据库的一组数据命令和一个数据库连接。无法继承此类。该类继承于system.data.common.dbdataadapter和实现接口system.data.idbdataadapter。采用adapter模式设计。

b) system.data.sqlclient.sqlconnection:sql数据库连接。表示 sql server 数据库的一个打开的连接。无法继承此类。

c) system.data.sqlclient.sqlcommandbuilder:sql数据库命令生成器。自动生成具有以下用途的单表命令:使对 dataset 所做的更改与关联的 sql server 数据库相协调。无法继承此类。采用builder模式设计。

另外还有一些,但是在本文中将用不到,所以这里也就不再叙述了。

2. oracle:

a) system.data.oracleclient.oracledataadapter:oracle数据适配器。表示用于填充 dataset 和更新oracle数据库的一组数据命令和到数据库的连接。无法继承此类。该类继承于system.data.common.dbdataadapter和实现接口system.data.idbdataadapter。采用adapter模式设计。

b) system.data.oracleclient.oracleconnection:oracle数据库连接。表示一个到oracle数据库的打开的连接。无法继承此类。

c) system.data.oracleclient.oraclecommandbuilder:oracle数据库命令生成器。自动生成用于协调 dataset 的更改与关联的oracle数据库的单表命令。无法继承此类。采用builder模式设计。

3. odbc:

a) system.data.odbc.odbcdataadapter:odbc类型数据数据适配器。表示数据命令集和到odbc数据源的连接,它们用于填充 dataset 以及更新该数据源。无法继承此类。。该类继承于system.data.common.dbdataadapter和实现接口system.data.idbdataadapter。采用adapter模式设计。

b) system.data.odbc.odbcconnection:odbc数据库连接。表示到odbc数据源的连接是打开的。

c) system.data.odbc.odbccommandbuilder:odbc数据库命令生成器。自动生成用于协调 dataset 的更改与关联的odbc类型数据源的单表命令。无法继承此类。采用builder模式设计。

4. oledb:

a) system.data.oledb.oledbdataadapter:odbc类型数据数据适配器。表示数据命令集和到oledb数据源的连接,它们用于填充 dataset 以及更新该数据源。无法继承此类。。该类继承于system.data.common.dbdataadapter和实现接口system.data.idbdataadapter。采用adapter模式设计。

b) system.data.oledb.oledbconnection:oledb数据库连接。表示到oledb数据源的连接是打开的。

c) system.data.oledb.oledbcommandbuilder:oledb数据库命令生成器。自动生成用于协调 dataset 的更改与关联的oledb类型数据源的单表命令。无法继承此类。采用builder模式设计。

我们需要什么样的数据操作器

当然是越简单越好了,功能倒不一定要强大,够用就行。希望能支持多种数据库,使用这个操作器的程序不用再考虑是那种数据库;希望能对多个数据库操作,一个项目使用多个数据库却不对增加编程复杂度;希望支持事务,失败能够自动回滚。功能嘛,能读取数据、更新数据就可以了。

通用数据操作器的思路

对数据库的操作其实就是两件事:出和进。出呢就是从数据库中读取数据,进就是将数据写回数据库,包括新增数据、更新数据、删除数据。

那么对这两个件事情该怎么做呢?

读取数据时,我们是打开一个连接,实例化一个数据适配器然后填充数据集,关闭连接,即可。这里要注意的是,由于数据集里的表经常是数据库里多个数据表join的结果,所以你甭想让操作器自动生成查询语句,得你自己写。

写入数据的时候,就会有一些麻烦,但因为都是执行单表操作所以你可以不用自己写sql语句,让操作器自己生成好了。

那么一步步怎么做呢?先打开一个数据库连接,再生成一个查询字符串,接着这两个东东实例化一个数据适配器,在生成一个commandbuilder的实例并注册为dataadapter的侦听器,接着配置事务。然后更新数据库,最后关闭连接。事务不能更早配置,是因为配置的事务之后便不允许数据适配器的命令为空。

思路有了,后面就很简单了,我们只需要为每一种数据库连接定义这些操作,然后根据实际情况调用就可以了。

当然我们不希望使用哪种数据库的由调用它的系统作为参数传入,定义在配置文件中似乎更好一些。

由于可能有多个数据库,所以我们应当体现这种情况。比如我们可以定义默认数据库连接为“dbcon”,数据库a的连接为“adbcon”。

由于要实现多张表的操作,所以我们要定义一个数据集表和表名的映射。

代码实现

首先定义一个枚举,以指定可以支持哪些数据库:

/// <summary>

/// 数据库类型枚举

/// </summary>

public enum dbtype

{

/// <summary>

/// sqlserver

/// </summary>

sqlserver,

/// <summary>

/// oracle

/// </summary>

oracle,

/// <summary>

/// oledb

/// </summary>

oledb,

/// <summary>

/// odbc

/// </summary>

odbc

}

定义一个类来扩展datatable:

/// <summary>

/// 用于更新数据库的数据表、库表名对

/// </summary>

public class datatableextend

{

/// <summary>

/// 数据表

/// </summary>

public system.data.datatable datatable;

/// <summary>

/// 数据表映射到数据库的表名

/// </summary>

public string datatablename;

/// <summary>

/// 用于更新数据库的数据表、库表名对构造函数

/// </summary>

/// <param name="mytable">用于更新数据库的数据表</param>

/// <param name="mytablename">数据表映射到数据库的表名</param>

public datatableextend(system.data.datatable mytable, string mytablename)

{

datatable = mytable;

datatablename = mytablename;

}

}

然后写一个类来读取配置文件并获取数据库连接字符串:

/// <summary>

/// dbsetting 的摘要说明。

/// </summary>

public class dbsetting

{

/// <summary>

/// 数据库连接字符串后缀

/// </summary>

public static string dbconnectionends

{

get

{

return "dbcon";

}

}

/// <summary>

/// 数据库类型后缀

/// </summary>

public static string dbtypeends

{

get

{

return "dbtype";

}

}

/// <summary>

/// 获取指定数据库的类型

/// </summary>

/// <param name="dbname">指定的数据库名</param>

/// <returns>指定数据库的类型</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>

/// 保存指定数据库的类型

/// </summary>

/// <param name="dbtype">指定数据库的类型</param>

/// <param name="dbname">指定的数据库名</param>

public static void savedbtype(dbtype dbtype,string dbname)

{

appconfig.saveappsetting(dbname + dbtypeends,dbtype.tostring());

}

/// <summary>

/// 获取指定数据库的连接字符串

/// </summary>

/// <param name="dbname">指定的数据库名</param>

/// <returns>指定数据库的连接字符串</returns>

public static string getdbconnectionstring(string dbname)

{

return appconfig.getappsetting(dbname + dbconnectionends);

}

/// <summary>

/// 保存指定数据库的连接字符串

/// </summary>

/// <param name="connectionstring">连接字符串</param>

/// <param name="dbname">指定的数据库名</param>

public static void savedbconnectionstring(string connectionstring, string dbname)

{

appconfig.saveappsetting(dbname + dbconnectionends,connectionstring);

}

}

接着为每一种数据库写一个类来执行针对该数据库的操作,例如针对sql server:

/// <summary>

/// 用于sql数据源操作的类

/// </summary>

public class sqlexec

{

/// <summary>

/// 获取数据库连接,读取由storm.appsetting的配置文件中dbname + "dbcon"的设置(如针对数据库test的配置键是“testdbcon”),若没有,则抛出异常

/// </summary>

/// <param name="dbname">要获取数据连接的数据库名</param>

/// <returns>得到的数据库连接</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();

//根据数据表的多少生成多个数据适配器并分别生成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();

}

//配置事务

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;

//更新数据库

mydataadapters[i].update(dts[i].datatable);

}

mytrans.commit();

sqlcon.close();

for(int i = 0; i < length ; i++)

{

dts[i].datatable.acceptchanges();

}

}

//如果失败,则自动回滚

catch(exception ee)

{

mytrans.rollback();

sqlcon.close();

for(int i = 0; i < length ; i++)

{

dts[i].datatable.rejectchanges();

}

throw ee;

}

}

/// <summary>

/// 从数据库中读取数据

/// </summary>

/// <param name="dt">要承载数据的数据表</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);

}

//自动生成查询语句

private static string getselectcommand(string datatablename)

{

string strget = "select * from " +datatablename;

return strget;

}

}

然后就是写一个类来根据实际情况调用这些东东了:

public class databaseexecute

{

private string dbname;

/// <summary>

/// 目标数据库

/// </summary>

public string dbname

{

get{ return dbname; }

set{ dbname = value; }

}

/// <summary>

/// 生成databaseexecute的实例

/// </summary>

public databaseexecute()

{

dbname = null;

}

/// <summary>

/// 用指定的目标数据库生成databasemodifier的实例

/// </summary>

/// <param name="dbname"></param>

public databaseexecute(string dbname)

{

this.dbname = dbname;

}

/// <summary>

/// 从数据库中读取数据

/// </summary>

/// <param name="dt">要承载数据的数据表</param>

/// <param name="selectstring">查询语句</param>

public void getdata(datatable dt, string selectstring)

{

//操作指定数据库

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);

}

}

//操作默认数据库

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>

/// 根据数据表组更新数据库

/// </summary>

/// <param name="dts">要更新的数据表组</param>

public void modifydatabase(datatableextend[] dts)

{

//操作指定数据库

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);

}

}

//操作默认数据库

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, “”);

}

}

}

这样,在项目中只要引用这个databaseexecute类就可以了。

最后,要注意的几点:

1. 对于多表操作而言,因为表间有关联,所以操作的顺序很重要,本构件操作的顺序是从数据表数组的前向后处理,请千万注意表处理的顺序!

2. 默认数据库连接由配置文件中“dbcon”的设置决定,非默认数据库连接由配置文件中“*dbcon”的设置决定,其中星号代表数据库标识

3. 默认数据库类型由配置文件中“dbcon”的设置决定,非默认数据库类型由配置文件中“*dbcon”的设置决定,其中星号代表数据库标识

4. 针对每一个数据库都有两个配置,分别是数据库连接和数据库类型。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 用设计模式开发通用数据库操作器-.NET教程,数据库应用
分享到: 更多 (0)