林佳一
摘要:在.NET的数据库应用程序开发中,如何选择合适的数据访问方式成为关键问题。首先介绍了.NET技术和ADO.NET的两种数据访问方式,然后从资源利用率、执行方式和使用场景三个方面,详细探讨了两种访问方式下对系统的性能消耗以及执行效率的影响,最后通过一个的具体实例对两种访问方法的应用效果进行比较,并给出了合理选择数据访问方式的建议,这对开发数据库应用系统具有实际参考意义。
关键词:ADO.NET; 连接方式的数据访问; 断开方式的数据访问;DataReader;DataSet
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)03-0013-03
A Discussion on Data Access Mode in ADO.NET
LIN Jia-yi
(Guangdong Communication Polytechnic,Guangzhou 510650,China)
Abstract: In development of .NET database application, how to choose the right data access mode becomes the key problem. This paper firstly introduces.NET technology and two kinds of ADO.NET data access, and then from the three aspects of resource utilization, implementation and usage scenarios, the impact on the performance of system and the execution efficiency in two kinds of access mode is discussed in detail, compared the application effect of a specific example of two access methods, and finally gives a reasonable choice of data access proposal, which has practical reference significance to the development of database application system.
Key words: ADO.NET; connected data access;disconnected data access; DataReader;DataSet
随着互联网+时代的到来,各行各业正经历着前所未有的管理模式的改变。无论单位规模大小,数据的存储、查询、统计和修改等操作是单位的日常工作中一个重要部分。为了满足目前网络环境下提出的对海量数据处理的新任务,开发应用系统时,软件开发者始终需要将如何加快数据处理的速度和提高数据的利用率放在首要位置。
数据库应用系统的开发作为软件开发的一个主要的分支,已经广泛应用到社会各个领域。大型的数据库应用系统一般采用C/S或B/S架构[1],当前两大主流开发语言系JAVA和.NET都可以在这两种架构上开发系统。.NET作为微软推出的面向Internet的新一代应用程序平台,其中涉及数据库访问的最关键技术是ADO.NET。比起以前的数据库访问技术,ADO.NET在实现程序之间的数据共享上具有优越性,它提供了连接和断开两种数据访问方式。对于这两种方式,以往文献中过多侧重于讨论访问过程,本文则从不同的角度,分析了ADO.NET的两种访问方式的操作执行,具体探讨了两者在查询、增加、删除、修改以及执行存储过程时的差异,并在实际中分别用两种不同的访问方式来实现系统,通过比较来总结出一些经验,这些对我们在开发过程中如何选择数据访问方式提供了一些参考借鉴。
1 相关技术
1.1 NET技术和ADO.NET
1.1.1 NET技术
随着互联网技术的飞速发展,需要开发出大量支持跨平台和多种架构的应用程序。而原有的开发平台已不能适应这种新变化。为了快速开发兼容性更好的大型应用程序,1998年12月,微软公司提出了.NET的新战略。微软对.NET的定义为:.NET是Microsoft面向XML Web服务的平台,它使用一种统一的、个性化的方式将信息、设备和人员紧密地联系在一起[2]。经过近二十年的发展,.NET已经成为当前主流的企业级应用开发平台。
.NET平台的核心是NET Framework。可以从两个角度来解读它,一方面.NET Framework是一个基础工具,用于构建基于互联网平台的各种应用程序;另一方面.NET Framework是一个丰富的类库,用于开发WinForm、Web、ADO.NET、GUI等各类应用程序。
.NET Framework由两个主要组件组成[3]:公共语言运行库(Common Language Runtime,CLR)用于代码编译和执行的集成托管环境,.NET应用程序并不直接和操作系统打交道,而是在CLR上执行,受CLR的管理;.NET Framework 类库,这个类库可以供不同的编程语言调用,诸如C#、VC++、VB.NET等,从而实现了跨语言编程。
1.1.2 ADO.NET
通常我们将数据库应用系统划分为前台和后台两个部分,前台可以用C#、JAVA等多种高级语言实现,后台数据库可以用多种数据库管理系统来创建,常见的有SQL Server、Oracle、DB2和MySQL等。显然,不同的语言访问不同的数据库时,用到的也是不同具体的数据访问方法。为了让前台程序方便访问后台数据库,有必要在它们之间建立一种数据访问模型来统一操作数据库的方式。至上世纪80年代以来,业界上相继出现了ODBC、OLE DB、ADO、JDBC等各种数据访问模型,而伴随着.NET技术出现,微软推出了面向Internet版本的、能高效地连接和访问数据庫的模型ADO.NET。
作为.NET Framework 的一个重要组件ADO.NET,ADO.NET实质上是一个类库,它在很大程度上封装了数据库访问和数据操作的动作。ADO.NET主要包含五个非常重要的类,分别是Connection类、Command类、DataReader类、DataAdapter类和DataSet类。使用ADO.NET访问数据库主要有三大特点。一是跨平台。可以访问多种关系型数据库,也可以是非关系型的数据,比如Email或者XML数据。二是效率高。在断开连接数据库的方式下,应用程序可以直接从临时数据集DataSet中获取数据,大大提高数据访问速度。三是安全性高。可以使用数据库中的存储过程和视图,并结合权限提供安全保障。
1.2 ADO.NET中数据访问方式
相比较ADO、JDBC等其他的数据库访问技术,微软的ADO.NET在数据库访问上处理得更为精细、过程更为复杂。ADO.NET完美融合了数据库中表、存储过程、视图、事务等各方面的应用,特别是对于同出一家SQL SERVER数据库管理系统。随着Internet发展,ADO.NET集成了XML,适应了Web应用程序的开发。面对各种不同数据库应用系统需求,ADO.NET提供了多样性的数据处理方式。根据数据库的使用状态,将ADO.NET划分为两种数据访问方式[4],如图1所示:
1)连接方式的数据访问
首先应用程序创建Connection对象,并设置好连接字符串后打开与数据库的连接,然后通过创建Command对象向数据库服务器发出执行SQL命令的请求,数据库服务器在执行完命令后将结果返回给应用程序。此时如果还需要执行其他数据库命令,就不用再次创建连接和打开连接,只需要用Command对象发出执行SQL命令的请求即可。最后当应用程序不再需要访问数据库时,才关闭数据库的连接。
2)断开方式的数据访问
首先应用程序创建Connection对象,并设置好连接字符串后打开与数据库的连接,然后通过创建与Command对象相关联的DataAdapter对象,通过DataAdapter对象的Fill方法将数据库中需要的数据取出存放在本地的缓存DataSet中,此时自动断开与数据库的连接,随后应用程序直接对DataSet进行相关数据操作,除非需要重新从数据库中取出数据或对将DataSet中的数据更新至数据库时,才会连接数据库。
这两种数据访问方式大量应用在ADO.NET系统的开发中,但是在具体实现中又有多种途径,总结为三种方法。第一种是使用ADO.NET控件,Visual Studio的工具箱中提供了各种ADO.NET控件,通过一次性拖放控件来实现与后台数据库的绑定,并可以在前台的显示控件中操作数据。这是最简单快捷编程方式;第二种是使用ADO.NET对象,在程序中使用ADO.NET对象提供的各种方法完成数据库操作。虽然这种方法需要更多编写代码,但是给编程者有更多拓展空间,编写出满足个性化需求的功能;第三种是混合使用控件和对象,兼顾两者优缺点,可以精简部分代码。
图1 数据访问方式
2 两种访问方式的比较分析
2.1资源利用率
连接方式的数据访问要求在整个程序运行过程中一直要和数据库保持连接。虽然数据库可以支持多用户连接,然而连接的资源毕竟有限,如果让一个数据库长时间连接并处于打开状态,将浪费较多的系统资源,从而会限制应用程序实现更多功能。
断开方式的数据访问则是将应用程序要经常要用到的数据存放在本地的DataSet中,于是应用程序可以直接到DataSet中提取数据,就不再需要与数据库保持连接了,这样可以让别的应用程序有更多的机会使用数据库,提高资源使用效率。
2.2执行方式
1)查询操作
在数据库中执行频率最高的是查询操作。使用SELECT语句执行完后会得到一个结果表,应用程序通过连接和断开两种数据访问方式获取到结果表。
对于连接访问方式,当查询到结果表只包含一个结果值,比如:执行一些带统计函数的SELECT语句,则执行Command对象的ExecuteScalar方法,获得的是一个Object类型值。将该值转换成其他类型后可以直接在程序中使用;当查询的结果表包含一行或多行记录时,则使用DataReader对象,它类似于一个读取数据的指针,指向服务器缓存中的结果表,读取一行数据就处理一行,如果读不到返回false。因此只需要一条数据记录的内存,内存占用非常小,但只能读取结果表中数据而不能对其修改,这种方式速度快。
对于断开方式的数据访问,无论查询的结果集中有一个还是多行数据,始终用DataSet存放。可以把DataSet看成是内存中的一个临时数据库,只要内存够大,可以在里面放一个表或多个表,甚至View都可以。但也有上限要求,DataSet可以容纳不超过十几万条数据。由于DataSet在本地内存中,里面的数据是从数据库中筛选出来的,因此在查找DataSet中数据时,耗时短,访问效率高。
2)增加、删除和修改操作
查询操作不会造成数据库中数据的改变,增加、删除和修改操作会对数据库产生实质的影响。应用程序在两种数据访问方式下更改数据库的具体实现方式截然不同。
连接访问方式下,通过Command对象的ExecuteNonquery方法执行Insert、Delete和Update这些SQL语句。应用程序可以获得执行完SQL命令后数据库受影响的行数,这往往是判断数据库是否修改成功的依据。该方式对执行SQL语句的表没有太多要求,单表或多表都可以。同时整个执行过程简单,一句代码直接即可完成數据库的更新。
断开访问方式下,应用程序不能直接修改数据库,只能修改DataSet。如何让DataSet修改后的数据同时反映到数据库中,此时,DataAdapter对象在DataSet和数据库之间架起了一座沟通的桥梁。执行DataAdapter对象的Update方法,会重新连接数据库,使Dataset与数据库实现同步更新。当更新数据库完成后,自动关闭连接。这种更新数据库的方式在应用时有一定条件限制,首先要求必须是针对单个表的操作;其次必须要求操作的表必须定义好主键;最后还要使用SqlCommandBuilder对象来自动产生与DataAdapter相关的修改命令对象Command。该方式具有较大的局限性,代码中涉及对象多,编写相对复杂,因此只是作为一个补充选择方案,实际中应用较少。
3)执行存储过程
将一段SQL操作命令设计成存储过程执行,有利于提高系统安全性,同時减少网络流通量。连接访问方式下执行存储过程首先需要设置Command的CommandType属性,然后将存储过程名赋给CommandText属性,最后根据存储过程返回值的类型选择相应的执行方法。整个执行过程简单,易于编程。断开访问方式下,可以通过设置DataAdapter的SelectCommand属性和调用Fill方法来完成,但是并不是所有的存储过程都可以正常执行,如果存储过程中有修改语句或没有返回值,代码会出问题。只能用于执行特定的存储过程。
2.3适用场景
面对多种访问数据库的方式,在不同的应用中选取合适的数据访问方法显得尤为重要,这直接影响决定着系统运行的效率。一般来讲,连接访问方式比较适合以下的一些场景。场景一:系统部署在一个局域网环境中并采用C/S架构,如果存在大量的查询数据库操作,不需要修改查询结果,DataReader是最好的选择。场景二:系统要求及时反映数据的变化,比如环境、交通监控系统,连接访问这种方式速度快,适用于实时要求高的系统。断开访问方式在下列场景中发挥更好的作用。场景一:系统有大量的用户使用,如果用断开方式,那么只有在更新数据库时才会连接数据库,提高资源利用率。场景二:系统部署B/S的环境中,比如网上办公,电子商务系统。这样先把数据库中所有数据都放到内存,然后都在本地机器中操作。选择用哪种方式也不是绝对的,要根据实际场景将两种方式结合起来,更好发挥各自优势。
3 基于两种访问方式下的应用实例
图2 运动员信息管理界面
以下实例基于C/S架构的学校运动会管理系统,开发中前台采用了Visual Studio2012,后台使用SQL Server2012。选取了其中一个运动员信息管理的编辑界面,如图2所示,分别用两种不同的数据库访问方式实现了查询、增加、删除和修改运动员信息的功能。下面列出了主要步骤代码。
3.1采用连接方式的数据访问
if (type == 1) //添加
{
s = string.Format("insert into athlete values('{0}','{1}','{2}','{3}','{4}','{5}')", txtID.Text.Trim(), txtName.Text.Trim(), cbGender.Text.Trim(), Convert.ToDateTime(txtBirth.Text.Trim()), txtPlaceOfOrigin.Text.Trim(), txtMemo.Text);
}
if (type == 2) //修改
{ … }
if (type == 3) //删除
{ … }
conn = new SqlConnection();
conn.ConnectionString = ConfigurationManager.ConnectionStrings["AthConn"].ConnectionString;
conn.Open();
SqlCommandcmd = new SqlCommand(s,conn);
cmd.ExecuteNonQuery();
…
3.2采用断开方式的数据访问
if (type == 1) //添加
{
dr = dt.NewRow();
dr["a_athleteid"] = txtID.Text.Trim();
dr["a_name"] = txtName.Text.Trim();
dr["a_sex"] = cbGender.Text.Trim();
dr["a_birth"] = Convert.ToDateTime(txtBirth.Text.Trim());
dr["a_address"] = txtPlaceOfOrigin.Text.Trim();
dr["a_memo"] = txtMemo.Text;
dt.Rows.Add(dr);
SqlCommandBuildersqlBuild = new SqlCommandBuilder(da);
da.InsertCommand = sqlBuild.GetInsertCommand();
}
if (type == 2) //修改
{ … }
if (type == 3) //删除
{ … }
da.Update(ds, "athlete");
ds.AcceptChanges();
dgvStudent.Refresh();
…
3.3实例分析
在上面的实例中,虽然两种数据访问方式都可以实现相同的功能,但是综合考虑各方面因素,往往会采用兩种访问方式相结合的模式。在实现将sportsmeet数据库中的athlete表数据 (下转第22页)
(上接第15页)
查找出来并显示在DataGridview控件的过程中,显然用DataReader读取速度快,但它只能一行行读取数据,也不能直接绑定到显示控件上,因此在这里最好用Dataset直接作为数据源,处理更简单。如果对athlete表数据进行修改,用DataAdapter对象的update方法受限制的条件多,用连接访问方式执行Command命令处理更为合适。综合上述分析,这里我们最好用断开访问方式做查询,用连接的方式做增加、删除、修改。
4 结论
在数据库应用系统开发过程中,我们的目标是追求运行的高性能和提高资源的利用效率。ADO.NET作为访问数据库的.NET技术,使得程序员从原来繁重编码工作中的解脱出来,以更方便、更直观的方式来操作数据。随着LINQ、Entity Framework、ASP.NET MVC等各种软件开发新技术不断发展,虽然这些技术对简化对数据库操作做了不少改进,但还有很多的新问题摆在面前。例如,如何结合当前大数据云计算技术[5],让.NET应用程序更高效访问数据;如何提高数据库应用程序的可维护性;如何保障数据的安全有效[6];这些还有待不断地探索和研究。
参考文献:
[1] 严勋,孙虎. 企业管理信息系统实现模式研究[J]. 微计算机信息,2007(11):31-32.
[2] 刘晓刚,吴俊峰. C# WEB数据库编程[M]. 北京:清华大学出版社,2010.
[3] 修乾. 基于Web的.NET应用系统开发[J]. 计算机工程,2003(21):185-186.
[4] 庄越,王槐彬. C#程序设计与项目实战[M]. 北京:电子工业出版社,2014.
[5] 覃雄派,王会举,等. 数据管理技术的新格局[J]. 软件学报,2013,24(2):175-191.
[6] 曾建国. 大数据时代数据库信息系统安全风险评估技术分析[J]. 信息安全与技术,2015(9):27-28.