zoukankan      html  css  js  c++  java
  • General框架如何实现多数据库支持

    关于用C#实现多数据库支持的方式,大家都会多少了解,本文从General框架的开发思路角度详细介绍General框架实现多数据库支持的方式,使更多的人了解General框架的底层实现并得到所需的相关知识。我在开发General框架之中,从网络中获取到了很多知识,对其他ORM框架亦有借鉴,其中借鉴最多的是NBear框架和NHibernate框架,我将从各处得到的开发思想融合进来,形成了我自己的开发方式。

    简单说来,General框架支持多数据库的实现思路,无非是以下几点:

    1Ado.Net的多数据支持

    2SQL的多数据支持

    3、数据管理器的多数据库支持

    下面将具体进行说明。

    1Ado.Net的多数据支持

    当我们初学C#的时候,会了解Ado.Net有五大对象,即Connection(连接对象)、Command(命令或执行对象)、DataReader(读取器对象)、DataAdapter(适配器对象)、DataSet(数据集对象),而我们开始常用的SqlHelper中,这五大对象是SqlConnectionSqlCommandSqlDataReaderSqlDataAdapterDataSet,后来可能会接触到支持多数据库版的SqlHelper,即DbHelper,这里面的五大对象会变为DbConnectionDbCommandIDataReaderDbDataAdapterDataSet,再后来我们发现其实SqlConnectionSqlCommandSqlDataReaderSqlDataAdapter分别是DbConnectionDbCommandIDataReaderDbDataAdapter的子类,即Ado.Net使用了抽象类来适应多数据库支持,所以编写支持多数据库的应用程序,只需要使用Db开头的Ado.Net对象就可以了。但是抽象类不能直接实例化怎么办,其实这里面还有一个工厂类用来创建抽象类的实例,即DbProviderFactory,但DbProviderFactory也是抽象类,仍然无法实例化,这时我们需要根据具体数据库类型,来使用不同数据库对应的Ado.Net的驱动中的DbProviderFactoryInstance就可以,各数据库对应的驱动类库和工厂类如下:

    序号

    数据库类型

    对应的驱动类库

    对应的工厂类

    1

    Access

    System.Data.OleDb(自带)

    OleDbFactory.Instance

    2

    Sqlite

    System.Data.Sqlite(需下载)

    SQLiteFactory.Instance

    3

    SqlServer

    System.Data.SqlClient(自带)

    SqlClientFactory.Instance

    4

    Oracle

    System.Data.OracleClient(自带)

    OracleClientFactory.Instance

    5

    MySql

    MySql.Data(需下载)

    MySqlClientFactory.Instance

    General.Data中有一个BaseProvider,这个类是一个抽象类,负责提供数据库对应的工厂类的实例,每种数据库类型需实现自己的Provider并继承于BaseProvider,并提供实际的工厂类实例。还有一个DbCommon类,这个类负责跟Ado.Net打交道,使用的都是Db版的五大对象,它的构造函数参数即是BaseProvider,即需要用具体的Provider实现来创建DbCommon,而DbCommon就可以用具体的Provider实现所提供的工厂类实例来创建Db版的五大对象,这样也就可以使DbCommon可以适应不同类型的数据库。

    2SQL的多数据库支持

    Ado.Net层面实现多数据库支持之后,由于Ado.Net实际不涉及SQL的拼装,并且各数据库在SQL的实现上都会有多少的差异,比如SqlServer的参数前缀是“@”,而Oracle的是“:”,SqlServer用中括号括起来表示标记名称,而Oracle用双引号括起来表示标记名称,再如Sqlite没有“Top”关键字而有类似的“Limit”关键字等等,所以要实现支持多数据库的ORM框架,在生成Sql的时候需要根据不同的数据库类型来进行区别。

    General.Data中有一个QueryBuilder类,这个类用来生成Sql语句,而这个类是抽象类,即每个数据库类型需要实现自己的QueryBuilder来区别不同的Sql语法,而通用部分的Sql,比如SelectInsertUpdateDelete等语句各数据库是一样的,所以不需要抽象而在抽象类中直接实现。QueryBuilder类不需要自身创建,而是通过BaseProvider的抽象方法GetQueryBuilder来由每个Provider的实现来创建,相应与QueryBuilder类似的SchemaManager也由BaseProvider的抽象方法GetSchemaManager来由每个Provider的实现来创建。这样,上层只要掌握Provider的创建,即可掌握对各数据库类型的支持。

    3、数据管理器的多数据库支持

    General.DataDataManager类是所有数据库操作的接口,上一段说过:只要掌握Provider的创建,即可掌握对各数据库类型的支持。所以DataManager的初始化,其实就是ProviderDbCommonQueryBuilderSchemaManager的创建过程,而有了Provider,其余三者都可以由Provider来创建,而且只需要增加Provider和其对应的QueryBuilderSchemaManager,就可以增加对更多数据库类型的支持。

    为了方便配置,General.Data中添加了DatabaseType枚举类型,将已经实现的数据库类型支持包含在其中。配置时,只需要指定DatabaseTypeConnectionStringDataManager就可以自动创建对应的Provider等类的实例,也就完成了初始化。

    在做多数据库支持时,还有一些意外的问题:

    1Sqlite数据库在读取数据时报“该字符串未被识别为有效的 DateTime ”异常

    这是由于Sqlite不支持当前系统的日期时间格式,需要在保存数据时,将DateTime类型的值.ToString(“s”),为了解决这个问题,在General框架中加入了实体属性格式化方法,在实体属性映射上加上 Format = “s”,然后将 DataManager.Default.UsePropertyValueFormat = true,即可进行自动格式化。

    2Access数据库在保存数据库时报“xxx字段不能为空”

    这是由于Access数据库表的文本字段未开启“允许空字符”,不愿开启这个选项的话可以设置DataManager. AccessConvertEmptyStringToNull = true,这样会自动将空字符转为DBNull值。

    3Oracle数据库在执行操作时报“xxx表或视图不存在”

    这是由于建表Sql对表名加了双引号而Sql语句中表名大小写不正确,或建表Sql没有双引号Oracle自动将表名大写而Sql语句中表名不是大写,推荐建表Sql不要对表名加双引号并设置DataManager.OracleConvertQuoteNameToUpper = true

  • 相关阅读:
    #入魔这些年#零度智控&模型控社区大型征文活动,万元大奖等你拿
    2013百度安卓巴士轻应用4城市巡展沙龙,免费报名啦
    专访高磊:安卓APK安全加固的引领者
    Android——程序移植 相关知识总结贴
    iPhone开发视频教程 Objective-C部分 (51课时)
    Android项目实战--手机卫士开发系列教程
    Android——BitMap(位图)相关知识总结贴
    《Linux内核设计与实现》读书笔记
    golang API 请求队列
    自定义Antd Pro 默认元素
  • 原文地址:https://www.cnblogs.com/lgyup/p/4616330.html
Copyright © 2011-2022 走看看