同时支持多种数据库

本文介绍在一个项目中同时支持多种数据库的实现方法

可以细分为2种场景:

  • 场景1:同时支持 A库是SQLSERVER,B库是MYSQL,C库是PostgreSQL ,....
  • 场景2:一套代码同时支持多种数据库,由部署时决定使用哪种数据库

实现思路

1,无论使用哪种数据库,都由数据库连接的配置来决定(示例中的2种配置方式可任选一种),例如:

<connectionStrings>
    <add name="sqlserver" providerName="System.Data.SqlClient"
            connectionString="server=192.168.1.1;database=MyNorthwind;uid=user1;pwd=xxx"/>

    <add name="mysql" providerName="MySql.Data.MySqlClient"
            connectionString="server=192.168.1.1;database=MyNorthwind;uid=user1;pwd=xxx"/>

    <add name="postgresql" providerName="Npgsql"
        connectionString="Host=192.168.1.1;database=mynorthwind;port=15432;Username=postgres;Password=xxx"/>
</connectionStrings>

<dbConfigs>
    <add name="s1" dbType="SQLSERVER" server="192.168.1.1" database="MyNorthwind" uid="user1" pwd="xxx" args="" />
    <add name="m1" dbType="MySQL" server="192.168.1.1" database="MyNorthwind" uid="user1" pwd="xxx" args="" />
    <add name="pg1" dbType="PostgreSQL" server="192.168.1.1" port="15432" database="mynorthwind" uid="postgres" pwd="xxx" args="" />
</dbConfigs>
  • 对于【场景1】,不同的【连接名称】表示要连接不同的数据库
  • 对于【场景2】,【连接名称】应该是固定的,只要在部署时切换 providerName 或者 dbType 就可以了



2,然后在代码中只使用【连接名称】

例如:

using( DbContext db = DbContext.Create("mysql") ) {
    //...... CURD 代码
}

using( DbContext db = DbContext.Create("pg1") ) {
    //...... CURD 代码
}

ClownFish的数据库操作相关类型不区分数据库,所以只要是标准的SQL,就能支持所有的数据库。



编写特定的数据库代码

有些数据库有特殊的命令, 【标准SQL】无法支持,只能编写【特定的数据库代码】,那么可参考下面示例来解决:

using( DbContext db = DbContext.Create("连接名称") ) {
    
    if( db.DatabaseType == DatabaseType.PostgreSQL ){
        // 在这里编写特定的数据库代码
    }
    else if( db.DatabaseType == DatabaseType.DaMeng ){
        // 在这里编写特定的数据库代码
    }
    else{
        // 其它数据库可通用的代码
    }

    // 或者使用 ProviderName 来区分数据库种类
    if( db.ProviderName == "Kdbndp" ){
        // 在这里编写特定的数据库代码
    }
    else{
        // 其它数据库可通用的代码
    }
}



使用 XmlCommand

如果项目中使用XmlCommand访问数据库,那么同时支持多种数据库会比较简单。

首先,配置一个 本地参数

ClownFish_XmlCommand_SupportMulitDbType=1

然后,只需要对特定数据库配置不同的XmlCommand即可,例如:

<XmlCommand Name="RandGetCustomer">
    <CommandText><![CDATA[select * from Customers limit 1 ]]></CommandText>
</XmlCommand>
<XmlCommand Name="RandGetCustomer.SQLSERVER">
    <CommandText><![CDATA[select top 1 * from Customers ]]></CommandText>
</XmlCommand>

这里定义了2个XmlCommand,其中

  • "RandGetCustomer.SQLSERVER" 是专门针对 SQLSERVER 定制的
  • "RandGetCustomer" 用于除SQLSERVER之外的所有数据库

针对特定数据库的 XmlCommand 命名规则:name.{DatabaseType}


其中 DatabaseType 是由 ClownFish 定义的一个枚举类型,
如果在 自行扩展BaseClientProvider 的类型中使用了DatabaseType不存在的名称,那么请使用对应的数字,例如:"RandGetCustomer.7777"

示例调用代码


string dbConnName = GetConnectionName();

using( DbContext db = DbContext.Create(dbConnName) ) {

    var customer = db.XmlCommand.Create("RandGetCustomer").ToSingle<Customer>();
}

上面这段代码在运行时,会根据连接的数据库类别自动选择合适的XmlCommand,当发现:

  • 数据库是 SQLSERVER 时,会选择 "RandGetCustomer.SQLSERVER"
  • 其它数据库类别时,会选择 "RandGetCustomer"