阅读目录

C#和VB数据访问的比较

C#中要进行一次普通的数据库查询,需要创建连接,再根据具体的数据库类型,创建相关的适配器对象,再创建命令对象,执行后,将结果填入到Dataset中,用户拿到Dataset后,再从其中的DataTable中取得数据。这种处理方式存在种种不便之处:

1、需要一系列复杂操作才能完成一个简单功能,涉及的对象多、实现的逻辑和自然的思维习惯有所不同。

2、对不同类型的数据库处理有所不同,用户需要记忆不同类型数据库之间细微的差异。

3、有些底层工作需要用户完成,如连接有效性的检查、出错后连接的重建等工作。

回顾微软的开发平台的发展历史,最有用户基础的莫过于Visual Basic了。1998年推出的VB6,在2014年的Tiobe 编程语言排行中仍在前十之列。

在VB6中,数据库的操作可谓简单至极,只要拖一个数据库的控件就可以使用大多数的数据库操作了。即使要用纯代码方式控制,也非常简单,通过以下步骤即可完成:

Set oCn=new connection
Set oRS=oCn.Excute(strSQL)
oCn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=db.mdb"
While Not eof(oRS)
'处理
oRS.MoveNext
Wend

上面的代码,懒得进VB去输入,直接手工输入的,估计也差不离,从另一个侧面也可以看出VB代码的简洁。习惯了这样简单的数据库访问方式,一直觉得C#中的数据库处理方式过于复杂。正因为如此,才不断摸索简化数据库访问的手段。经过各种思路的演化,由繁到简,最终形成一个适用性较强的、经过多次开发实践检验的快速数据访问机制AccessDB。

AccessDB的设计

从我个人的经验出发,回顾参与过的各种软件开发项目,数据库访问的要求大同小异,用20/80法则可以很好地概况:80%的情况下,只会用到20%的功能。因此,只要能够封装这20%的功能,就可以适应绝大多数数据库操作的要求了。如果恰好需要剩余的20%的话,那就按照常规的方法来访问即可。

综合起来,希望数据访问机制能够达到以下的目标:

1、足够简单。简单到无需记忆。

2、适用多种数据库。中小型应用系统采用的数据库类型往往多变,甚至同一个项目在不同阶段更换数据库也很常见(我的习惯是用Access开发,后期换Sql Server)。因此,必须要能够在多种常用数据库间任意迁移。当前支持的有Access/Sqlserver/Sqlite,可以做到在切换数据库时,只要修改连接串,代码无需做任何改动。

3、具备扩展性。这套数据访问机制,是随着需求的不断丰富,不断重构、扩展,而变成当前的样子的,未来可能还会不断增加新内容。最近的一个升级,就是解决了以前web.config中配置mdb文件路径时,必须要使用绝对路径的问题。

基于以上的设计目标,经过不断的总结,实现了一个以AccessDB类为核心的数据库访问机制。AccessDB是一个入口类,无需实例化,提供了常用的静态方法。使用者只需记住AccessDB类名即可访问绝大多数的数据库功能。在整个CommonCode库中,保持了类似的命名风格,访问Web的入口类为AccessWeb,访问文件的入口类为AccessFile……

AccessDB会根据初始化条件(配置文件或初始化命令)创建具体的数据访问实体对象,如SqlserverDB、SqliteDB等。这些对象都实现了IDB接口,IDB接口的功能包括了我们常用的数据库访问功能。

interface IDB  //数据库的实际访问对象
{
bool OutputSelectLog { get;set;} //是否输出选择日志
bool OutputNonQueryLog { get;set;} //是否输出非选择操作的日志
bool IsOpen { get; } //连接是否打开 void CloseConn(); //关闭连接
DataTable GetData(string sqlstr); //通过sql语句,获取数据集
DataTable GetPage(string strSQL, int PageSize, int PageNo, string KeyField, bool IsStringKey);
DBResult DoNonQuery(string sqlstr); //非选择查询
}

AccessDB中直接调用IDB接口对象,执行各种操作。因为AccessDB的主要方法都是静态方法,因此IDB对象也必须是静态对象。换言之,在系统运行中,数据库访问对象只有一个。在少数特殊的情况下,需要同时操作多个数据库,这时,可以通过直接创建IDB对象的方法,来访问其他的数据库。AccessDB的结构如下图:

上图是在VS的类图基础上,按类别进行了修改调整,以便看得更加一目了然。dbobject就是IDB的静态对象,属性和方法中的第一层方法,都是和IDB接口对应的,一方面这些方法本身就是通用性强、常用的方法,另一方面,刻意把这些方法和IDB的接口方法保持一致,这样,用户在自行创建SqlserverDB、SqliteDB对象时,用到的方法和AccessDB是相似的,降低了使用的复杂性。

方法中的第二类,是完成静态连接的创建、维护、检查错误等工作的,这部分代码经过不断的修改,已经比较健壮。也就是说,使用AccessDB开发的程序,在数据库连接方面,是比较稳定的,不管是网站,还是桌面程序,长期运行(制作的若干网站持续运行很少因为数据库而出问题,桌面程序中写过一个数据采集设备的通信服务器,也可以长期运行)数据库功能都保持正常;在中等并发节点访问的情况下(碰到算多的情况是200左右的终端同时访问,持续2节课)也能够正常工作。

方法中的第三类,是常用数据操作,在本系列的另外一个帖子(【6】页面数据和控件的自动交换机制)中,用到Add和Update以及GetEmptyRow,这些都是实际数据访问中常用的方法。这些方法本质上还要调用标准的数据访问接口来实现,只在AccessDB中提供这些实用数据操作,在具体的IDB中不提供这些方法。

数据库的连接

连接可以通过两种方式创建,一种方式是隐式方式,即通过配置文件来控制连接的创建,一种是显示方式,调用一个方法来完成连接的创建。

隐式方式常用于web应用程序中连接的创建,显式方式常用于桌面应用程序中连接的创建。

1、隐式的连接

通过配置文件创建连接时,使用的数据库连接串和普通的数据库连接串完全一致。唯一特别的要求,是配置的连接串的键值必须为mainDB2。因为最早的连接串名使用了mainDB2,后来尽管不断升级,为了和前面的代码兼容,这个就一直没有改变。

连接串格式兼容正常的连接串,以下是连接串的各种写法:

Web.Config中的标准的连接串
<configuration>
  <connectionStrings>
    <add name="mainDB2" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=f:\cx\page.mdb"/>
  </connectionStrings>
</configuration> 由于数据库连接方式多种多样,以下是各种常用的数据库连接方式的写法,相对路径连接串
<add name="mainDB2" connectionString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source=db\page.mdb"/> Sql Server连接
<add name="mainDB2" connectionString="Provider=sqloledb;Data Source=192.168.1.5;Initial Catalog= jsjxy;UserId=sa;Password=jjssjj;"/> Sql Server本地Windows方式认证
<add name="mainDB2" connectionString="Provider=sqloledb;Data Source=;Initial Catalog=pubs;Integrated Security=SSPI;"/> 别名方式
<add name="connName" connectionString="mainDBNew"/>
<add name="mainDBNew" connectionString="Provider=Microsoft.Jet.OLEDB.4.0; Data Source=f:\cx\page.mdb"/> Sqlite连接
<add name="mainDB2" connectionString="DataSource=c:\\jsjxy.db;Version=3;"/>   加密方式连接
<add name="mainDB2" connectionString="DataSource=c:\\jsjxy.db;Version=3;Password=EPAS1yGV1IGaEPAS;"/>

2、显式连接的创建

通过CheckConn方法可以显式创建连接。CheckConn方法的主要作用是检测全局的连接是否存在,如果存在,则返回,否则就根据传递的参数创建连接——参数就是前面提到的各种形式的连接串。CheckConn方法是建立和保持连接的主要方法,具有以下功能:

1) 如果传递连接串,则创建连接;

2) 如果传递空串,则检查原链接是否有效,如果失效则使用保存的连接串重建连接;

3) 自动检测web.config文件,根据指定的连接串创建连接;

CheckConn的实现代码如下所示:

public static bool CheckConn(string ConnectString)
{
  //构造对象
  CreateDBObj(ConnectString);
  return dbobject.IsOpen;
}

通过调用CreateDBObj方法来创建连接。CreateDBObj方法根据连接串中的特征信息,创建不同的IDB对象,并将连接的配置信息保存起来,便于在任何时候都可以恢复连接。

为了便于使用,两个辅助的函数GetAccessConnectionString和GetSqlServerConnectionString,构造常见的连接串。

连接的保持,采用了被动方式进行。即不进行主动的定期检测,而是在每次调用数据库功能的时候进行检测。如果遇到异常,则重建连接并重新执行操作。

三种主要操作

1、查询数据集

调用IDB接口对象dbobject中的GetData方法,将数据返回。

//数据库的查询方法
public static DataTable GetData(string sqlstr)
{
  CheckDBObj(); //检查对象是否存在
  return dbobject.GetData(sqlstr);
}

其中dbobject是根据连接所创建的具体的实现类。

2、执行非查询操作

非查询操作的执行和查询一样,都是调用IDB对象的相应方法来实现。

public static DBResult DoNonQuery(string sqlstr)
{
  CheckDBObj(); //检查对象是否存在
  return dbobject.DoNonQuery(sqlstr);
}

3、按分页查询

分页功能是Web应用程序中最为常用的功能,但是,如果按照Visual Studio的分页的方式,则每次需要查询出所有的数据,再传递给显示控件,这种处理模式在数据量庞大的时候,将会造成巨大的浪费。因此,对于分页往往需要自行定义,每次检索只查询用到的那一页数据。一般的做法,是通过存储过程来完成,但考虑到多种数据库的兼容,因此把分页功能集成到快速访问框架中。

AccessDB的GetPage同样需要调用IDB对象的方法:

public static DataTable GetPage(string strSQL, int PageSize, int PageNo, string KeyField, bool IsStringKey)
{
  return dbobject.GetPage(strSQL, PageSize, PageNo, KeyField, IsStringKey);
}

分页的方法没有什么特别的,都是来源于网上的,经过测试,效率还能接受而已。

错误输出及调试

AccessDB的调试非常简单,所有重要操作都会跟踪并输出日志信息。日志系统采用另一篇博文提到的基于Log4Net的日志系统

当AccessDB出错后,可以从错误日志中看到详细的信息。如果希望了解AccessDB执行的具体细节,可以通过IDB的两个属性OutputSelectLog、OutputNonQueryLog来控制。OutputSelectLog属性,决定是否输出执行的每一个Select语句;OutputNonQueryLog属性,决定是否输出执行的非查询类的语句。默认情况下,二者都关闭。

小结

以AccessDB为中心,提供了一套快速的数据库访问机制,通用的使用步骤如下:

1、引用CommonCode.dll,Log4Net.dll。把log4net.config复制到应用程序文件夹下。

2、初始化(web.config或者CheckConn)

3、GetData/Getpage查询,返回DataTable

4、DoNonQuery执行查询

5、在log文件夹下查看输出

【7】AccessDB快速数据访问的更多相关文章

  1. FoxOne---一个快速高效的BS框架--数据访问(Dao)

    FoxOne---一个快速高效的BS框架--(1) FoxOne---一个快速高效的BS框架--(2) FoxOne---一个快速高效的BS框架--(3) FoxOne---一个快速高效的BS框架-- ...

  2. ASP.NET Core模块化前后端分离快速开发框架介绍之3、数据访问模块介绍

    源码 GitHub:https://github.com/iamoldli/NetModular 演示地址 地址:https://nm.iamoldli.com 账户:admin 密码:admin 前 ...

  3. 同时支持EF+Dapper的混合仓储,助你快速搭建数据访问层

    背景 17年开始,公司开始向DotNet Core转型,面对ORM工具的选型,当时围绕Dapper和EF发生了激烈的讨论.项目团队更加关注快速交付,他们主张使用EF这种能快速开发的ORM工具:而在线业 ...

  4. 架构从最简单的数据访问框架(ORM)到资源调度和治理中心(SOA)说起

    随着互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,亟需一个治理系统确保架构有条不紊的演进. 单一应用架构当网站流量很小时,只需一个应用,将 ...

  5. [翻译]比较ADO.NET中的不同数据访问技术(Performance Comparison:Data Access Techniques)

    Performance Comparison: Data Access Techniques Priya DhawanMicrosoft Developer Network January 2002 ...

  6. 数据访问层DAL(数据库访问抽象类DataProvider)

    晒晒数据访问层DAL,看看你的项目数据访问层使用的是什么形式,数据访问性能比较 采用什么样的数据访问形式是软件编码很重要的一个环节,良好的数据访问形式不仅能够提搞代码的执行效率,协作能力,更重要的是对 ...

  7. 基于Oracle OCI的数据访问C语言接口ORADBI .

    基于Oracle OCI的数据访问C语言接口ORADBI cheungmine@gmail.com Mar. 22, 2008   ORADBI是我在Oracle OCI(Oracle 调用接口)基础 ...

  8. Springboot数据访问,棒棒哒!

    Springboot对数据访问部分提供了非常强大的集成,支持mysql,oracle等传统数据库的同时,也支持Redis,MongoDB等非关系型数据库,极大的简化了DAO的代码,尤其是Spring ...

  9. ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法

    一.前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实现对于数据库的快速访问,后来,ORM(Object Relatio ...

随机推荐

  1. Java 中的浮点数取精度方法

    Java 中的浮点数取精度方法 一.内容 一般在Java代码中取一个double类型的浮点数的精度,四舍五入或者直接舍去等的方式,使用了4种方法,推荐使用第一种,我已经封装成工具类了. 二.代码实现 ...

  2. 浅谈期望的线性性(可加性)【CodeForces280c】【bzoj3036】【bzoj3143】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=63399955 向大(hei)佬(e)势力学(di ...

  3. [BalticOI2002]Bicriterial routing

    OJ题号: BZOJ1375.ECNU1468 题目大意: 给定一个无向连通图,每条边有两个权值w1和w2.定义一条路径是优秀的当且仅当没有别的路径满足两个权值的和都比该路径小,求s到t的优秀路径条数 ...

  4. BZOJ 3876: [Ahoi2014]支线剧情 带下界的费用流

    3876: [Ahoi2014]支线剧情 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3876 Description [故事背景] 宅 ...

  5. vue父子组件使用时遇到的一个问题

    子组件一定要写在父组件之前,例如: //子vue,这里遇到一个坑,那就是子vue一定要写在父vue前面,不然会报错. Vue.component('todo-item', { template: $( ...

  6. centos7安装redis-4.0.1集群

    试验机操作系统:CentOS Linux release 7.2.1511 (Core) 本文的目的是教会大家快速搭建redis集群,完了再深入学习. 试问如果不上手试验,看的资料再多有个毛用? 下载 ...

  7. Git_搭建Git服务器

    在远程仓库一节中,我们讲了远程仓库实际上和本地仓库没啥不同,纯粹为了7x24小时开机并交换大家的修改. GitHub就是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想 ...

  8. Google的Shell开发规范

    官方:https://google.github.io/styleguide/shell.xml 中文: http://zh-google-styleguide.readthedocs.io/en/l ...

  9. 使用CSS3的@media来实现网页自适应

    如今,电脑显示器的屏幕分辨率向越来越大发展,而手机等移动设备终端的分辨率却不可能大到哪里去.越来越多的网站,开始让自己的页面自适合各种分辨率,在小分辨率下显示基本的内容,在大分辨率下显示全部功能,甚至 ...

  10. 调试查看CLR运行代码

    SOS (Son of Strike)调试扩展可以让我们在调试过程中查看CLR运行代码.SOS.dll随.NET一起安装,对于.NET 4.0来说,SOS.dll的所在位置是:C:\Windows\M ...