工具包类库介绍
在.NET Framework的System.Data.Common命名空间下定义了针对所有数据库的Connection、Command、DataAdapter以及DataReader对象的抽象类,分别是DbConnection、DbCommand、DbDataAdapter及DbDataReader,在这些抽象类中定义了针对所有数据库的通用方法和属性。这些通用的方法和属性不光存在于.NET Framework中微软提供的针对ODBC、OleDB、Oracle、SQL Server类中,为微软未提供、有数据库厂商单独提供的ADO.NET类中也需要提供这些方法和属性给开发人员。
图1 System.Data.Common命名空间
一般来讲针对不同的数据库类型,我们需要引用不同的命名空间来通过其中的方法对对应的数据库进行访问。正如图1所示,SQL、OleDb和Odbc数据库都提供了极为类似的接口去访问数据库中的信息。除此之外,在System.Data.Common命名空间下还提供了两个类,一个是DbProviderFactories,另一个是DbProviderFactory数据库连接,DbProviderFactories类提供的方法有两个(包括一个重载形式),GetFactoryClasses()方法返回在系统中注册的DbProviderFactory类,GetFactory()的两个重载方法都是返回一个指定的DbProviderFactor抽象类,在DbProviderFactory抽象类中又定义了创建DbConnection、DbCommand、DbDataAdapter及DbDataReader的方法。而不同的数据库访问类程序集中又都提供了对DbProviderFactory这个抽象类的实现(包括所有由数据库厂商提供的ADO.Net类)。所以我们要解决的问题是如何创建针对不同数据库的DbProviderFactory这个抽象类的实现。下面我们将把所有数据库类提炼出来,编写一个数据库通用类,这样只需要一个接口就可以访问不同的数据库类型。在实际操作中,用户只需要提供数据库类型和数据库连接字符串,然后就可以通过通用的SQL语句对数据库进行访问了。常见的SQL语句语法可以参考文末链接1。
我们封装的数据库类的类图如图2所示。我们提供了一个名称为“DbProviderType”的枚举类型,使用者需要根据自己使用的数据库类型选择对应的枚举项。在DbOperation这个类中包含了一个“ConnectionString”的属性,这是数据库的连接字符串信息,不同的数据库连接字符串格式也会有差异,具体方式可以参考文末链接2。此外,在类中我们对不同数据库DbConnection、DbCommand、DbDataAdapter及DbDataReader进行了封装,然后对外提供ExecuteNonQuery()、ExecuteScalar()、ExecuteDataReader和ExecuteDataTable()这四个执行命令的方法就可以完成对数据库所有的操作了。
图2 通用数据库类的类图
针对这四个方法的解释如下,在范例中我们将会学习到每种方法具体的使用步骤:
ExecuteNonQuery():一般用于UPDATE、INSERT和DELETE语句是否操作成功。唯一的返回值是受到命令影响的行数,如果影响行数为0的话,则证明操作是不成功的,大于0则证明操作成功;
ExecuteScalar():执行查询并返回查询所返回的结果集中第一行的第一列,所有其它的列和行将被忽略。一般用于从SQL语句返回一个结果,如给定表中的记录个数或者当前服务器时间。返回值为一个对象(object),可以根据需要把对象强制转换为合适的类型;
ExecuteDataReader():DataReader(数据读取器)是从数据源中选择某些数据最简单高效的办法,返回的DatReader对象提供了“游标”形式的读取方法,当从结果中读取一行完毕后“游标”会继续读取到下一行,每次调用都会返回一行数据;
ExecuteDataTable():这是四个方法中功能最强大的,返回的DataTable(数据表)对象非常类似于实际物理的数据库表,它由一组特定属性的列组成,可能包含0行或者多行数据。数据表也可以定义主键(可以是一列或者多列),列上也可以包含约束。数据表读取的数据一般用DataGridView控件显示会比较直观方便。
最后,这里有一点很重要的说明。我们封装的类中所有数据库的打开连接操作都是在上述四个方法的内部自动实现的,所以无需手动去编写代码。而对于关闭连接操作,C#提供了垃圾回收器机制数据库连接,它会在未来的某个时刻自己去释放资源,但是我们无法确定这个过程会在什么时候发生。忘记关闭数据库连接可能会导致.NET可执行程序的各种问题。这里我们使用using语句块来确保当块中代码退出时会自动关闭数据库连接来确保资源已经被释放。当然我们也可以调用Close()语句来手动关闭数据库连接。具体实现代码如下:
publicDbDataReaderExecuteReader(stringsql,IList>parameters,CommandTypecommandType)
{
DbCommandcommand=CreateDbCommand(sql,parameters,commandType);
command.Connection.Open();
returncommand.ExecuteReader(CommandBehavior.CloseConnection);
}
范例说明
范例提供了利用我们上面封装的通用数据访问类对Microsoft SQL Server和Microsoft Access这两种常见数据库的访问方式。首先我们需要在数据库中分别创建如图3和图4所示的数据表(SQL Server中的表需要自己创建,Access文件位于“JY-DataBaseAccess范例binDebug”。可以看到表中包含了常见的数据类型例如字符串、数值、布尔等。
图3 Microsoft SQL Server中的数据表
图4 Microsoft Access中的数据表
运行范例程序,可以看到有四个页面连接、读取、查询和修改,每个页面分别展示了不同的数据库访问方式。下面对每个页面的功能进行详细的说明。
连接
在数据库连接类型中目前可以选择SqlServer和Access,当然如果有更多数据库类型也可以直接进行添加,基本上常见的数据库包括SqlServer,MySql,Oracle,ODBC,OleDb都已经在通用类中进行了封装。选择不同的数据库类型可以看到对应的ConnectionString(连接字符串),如图5所示。
图5 Access数据库的ConnectionString
读取
单击选项卡进入读取页面,单击读取按钮,可以读取当前表中所有的数据并显示在DataGridView中。双击任一列首可以对列进行排序。
图6 读取页面
查询
单击选项卡进入查询页面,在耗时区间内输入最小值和最大值,然后单击搜索按钮,可以看到如图7所示的搜索结果。从中可以看到所有测试项的最少时间、最多时间以及符合耗时区间的所有匹配项。
图7 查询页面
修改
单击选项卡进入修改页面,在页面上可以对数据库执行查询、插入、更新和删除操作。
图8 修改页面的数据库更新操作
图9 修改页面的数据库插入操作
图10 修改页面的数据库删除操作
代码解释
下面我们对代码的核心部分做一些解释和说明,其余可以参考代码的注释部分。
参考链接:
1
2
END
锐视未来,携手简仪,一起开创开源测控之路。
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688