Home  >  Article  >  Database  >  【7】AccessDB快速数据访问

【7】AccessDB快速数据访问

WBOY
WBOYOriginal
2016-06-07 15:56:381294browse

阅读目录 C#和VB数据访问的比较 AccessDB的设计 数据库的连接 三种主要操作 错误输出及调试 小结 回到顶部 C#和VB数据访问的比较 C#中要进行一次普通的数据库查询,需要创建连接,再根据具体的数据库类型,创建相关的适配器对象,再创建命令对象,执行后,将

阅读目录

  • C#和VB数据访问的比较
  • AccessDB的设计
  • 数据库的连接
  • 三种主要操作
  • 错误输出及调试
  • 小结

    回到顶部

    C#和VB数据访问的比较

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

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

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

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

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

    image_thumb1

    在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的结构如下图:

    AccessDB_thumb1

    上图是在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文件夹下查看输出

    分类: CommonCode快速代码集
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn