• 打造自己的数据访问层(三)


    上一篇打造自己的数据访问层(二)中,我们已具体实现了数据访问层对应的功能,该进行收尾工作了,先来看段代码,试试上一篇实现的功能:
    View Code
    string sqlText = "SELECT ID, NAME, VAL FROM TEST";
    string columns = "ID, NAME, VAL";
    DataSet ds
    = new DataSet();
    DataExecutor execObj
    = new MSSqlExecutor();
    DataMapping map
    = new DataMapping();
    map.ExecuteObject
    = execObj;
    map.TableName
    = "TEST";
    map.KeyColumns
    = "ID";
    map.Columns
    = "ID, NAME, VAL";
    DataMapping map
    = new DataMapping(execObj.GetInstant(), "TEST", "ID", columns);
    map.Fill(sqlText,
    "TEST");
    map.SetCommands(DataCommandType.Insert
    | DataCommandType.Update | DataCommandType.Delete, ds);
    //DataTable方式进行增、删、改
    bool isSuccess = execObj.Update();

    果然已经完成了对数据库的读写操作了,至少不用再写大段的参数传递代码,功能都已经实现了,是不是就完成了?
    仔细看看上面的代码,实际上还有问题尚未解决,看看这句:
    DataExecutor execObj = new MSSqlExecutor();

    竟然在代码里直接实例化一个MSSql的执行对象,这样一开始提出的数据库之间的切换问题根本就没有从本质上解决。
    再回过头来看上一篇,有一个方法public IDbConnection GetConn(),用来获取数据连接对像,之前并没有说明其如何实现。
    我们知道DBConnection有两个关键信息:
    1、与哪种类型的数据库产生连接,这个前面已经解决了。
    2、传递与数据库连接的帐号信息、访问库信息的ConnectionString,这个并没有提及。
    看看第二点以前是怎么做的:
    View Code
    public IDbConnection GetConn()
    {
    if (conn != null)
    {
    return conn;
    }

    conn
    = new SqlConnection();
    conn.ConnectionString
    = 连接字串;
    return conn;
    }

    上面出现了连接字串,这个字串从哪来?

    总结下,要完成最终的数据访问输出,还需要解决两个问题:
    1、动态进行不同数据库之间的切换。
    2、解决数据连接字串的来源问题。

    接着就来解决这两问题,先解决第二个问题,有个比较简单的方法,将连接字串写入配置文件中去,数据访问层只需知道它传递过来KEY值:
    <appSettings>
    <add key="ConnStr" value="server=.;uid=sa;password=123456;database=DATA_BASE;max pool size=300"/>
    </appSettings>

    第一个问题解决了,只剩下最后一个问题了,如何动态切换不同的数据库,也就是说,在使用的时候不需要自己NEW一个对象,而是通过第三方来创建一个对象,实际上,设计模式里已提出了方案,创建型模式,有兴趣的朋友可以自行研究,我们这里只需要用到简单工厂模式:
    View Code
    public sealed class ExecutorFactory
    {
    public static DataExecutor Create()
    {
    return Create(DatabaseType.MSSql);
    }

    public static DataExecutor Create(DatabaseType dbType)
    {
    AbstractDataBase dataBase
    = null;
    Switch(dbType)
    {
    case DatabaseType.MSSql:
    dataBase
    = new MSSqlDataBase();
    break;
    case DatabaseType.Oracle:
    dataBase
    = new OracleDataBase();
    break;
    }

    return dataBase.Create();
    }
    }

    现在可对这句代码进行替换了:DataExecutor execObj = new MSSqlExecutor();
    替换为:DataExecutor execObj = ExecutorFactory.Create();
    至此,问题都解决了,切换数据库是只需更改DatabaseType为相应的数库类型。 
    接下来再考虑下,如果改变数据库类型也不需要变动程序,能不能实现?
    还是利用配置文件,只是此时提供的不是类型字串,而是实际的数据执行者程序集信息,再利用.NET的天然优势反射可以实现了。
    最终配置文件为:
    <appSettings>
    <add key="ConnStr" value="server=.;uid=sa;password=123456;database=DATA_BASE;max pool size=300"/>
    <add key="DBExecutor" value="FM.DataAccess, FM.DataAccess.MappingExcuter.MSSqlExecutor"></add>
    </appSettings>

    改造后的工厂:
    View Code
    public sealed class ExecutorFactory
    {
    public static DataExecutor Create()
    {
    return Create(null);
    }

    public static DataExecutor Create(string dataBaseTypeKey)
    {
    return Create(dataBaseTypeKey, null);
    }

    public static DataExecutor Create(string dataBaseTypeKey, string connStrKey)
    {
    if (string.IsNullOrEmpty(dataBaseTypeKey))
    {
    dataBaseTypeKey
    = "DBExecutor";
    }

    string[] sltDataBaseType = ConfigReader.Read(dataBaseTypeKey).Split(',');
    string asselblyName = sltDataBaseType[0];
    string nameSpace = sltDataBaseType[1].Trim();
    Assembly assembly
    = Assembly.Load(asselblyName);
    DataExecutor execObj
    = assembly.CreateInstance(nameSpace) as DataExecutor;
    execObj.SetConnectionString(connStrKey);

    return execObj;
    }
    }


    到此为止,数据访问层最终完成,当然这里还有很多问题有待解决,但其基本框架已形成了,以此为依据,根据业务变化,实现自己的扩展,不断更新,最终才能真正形成完善的数据访问层。

    下面提供本文的示例代码:
     数据访问层示例
  • 相关阅读:
    前台线程与后台线程,AfxGetApp>GetMainWnd()与AfxGetMainWnd的不同 (转)
    详细解说 STL 排序(Sort) (转)
    (转)怎样从一个DLL中导出一个C++类
    HTTP协议之状态码详解(转)
    关于列表(ListCtrl)控件的界面基础知识
    C++序列化(转)
    vs2008修改Menu(菜单)资源ID的方法。
    怎样解决VC中滚动条最大滚动值不能超过32767的问题
    < Photoshop CS 专栏 >颜色(二)
    C#使用BinaryReader类读取二进制文件
  • 原文地址:https://www.cnblogs.com/FlySoul/p/2040292.html
Copyright © 2020-2023  润新知