投递文章投递文章 投稿指南投稿指南 RSS订阅RSS订阅

SmartPublisher设计之旅 — 数据库访问层设计

来源:cnBLOGs 发布时间:2008-01-11 收藏 投稿 字体:【

其他数据库访问类
using System;
using System.Data;
using System.Data.OleDb;

namespace PublisherDB
{
    public class OleDBOperator : DBOperator
    {
        private OleDbTransaction transaction;
        private bool inTransaction = false;

        private OleDbConnection conn;
        public override IDbConnection Connection
        {
            get { return this.conn; }
        }

        public OleDBOperator(string strConnection)
        {
            this.conn = new OleDbConnection(strConnection);
            DBConfig.PooledConnectionCount++;
        }
        public override void Open()
        {
            if (conn.State.ToString().ToUpper() != "OPEN")
                this.conn.Open();
        }
        public override void Close()
        {
            if (conn.State.ToString().ToUpper() == "OPEN")
            {
                this.conn.Close();
                DBConfig.PooledConnectionCount--;
            }
        }
        public override void BeginTrans()
        {
            transaction = conn.BeginTransaction();
            inTransaction = true;
        }
        public override void CommitTrans()
        {
            transaction.Commit();
            inTransaction = false;
        }
        public override void RollbackTrans()
        {
            transaction.Rollback();
            inTransaction = false;
        }
        public override void ExecuteSQL(string sql)
        {
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = this.conn;

            if (inTransaction)
                cmd.Transaction = transaction;

            cmd.CommandText = sql;
            cmd.ExecuteNonQuery();
        }
        public override object ExecuteSQLForObject(string sql)
        {
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = this.conn;

            if (inTransaction)
                cmd.Transaction = transaction;

            object obj = cmd.ExecuteScalar();
            if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
            {
                return null;
            }
            else
            {
                return obj;
            }
        }
        public override DataSet ExecuteSQLForDataSet(string sql)
        {
            OleDbCommand cmd = new OleDbCommand();
            cmd.Connection = this.conn;

            if (inTransaction)
                cmd.Transaction = transaction;

            DataSet ds = new DataSet();
            OleDbDataAdapter ad = new OleDbDataAdapter();
            cmd.CommandText = sql;
            ad.SelectCommand = cmd;
            ad.Fill(ds);

            return ds;
        }
    }
}
         你可能已经发现了一个问题,我们究竟用三个访问类中的哪个呢?其实只要根据DBConfig中的DBType的值判断。所以调用时,实现如下:

DBOperator db;
if (DBConfig.DBType=="SQLSERVER")
{
    db=new SqlDBOperator("SQLSERVER连接字串");
}
else if (DBConfig.DBType=="ORACLE")
{
   db=new OracleDBOperator("ORACLE连接字串");
}
else
{
   db=new OleDBOperator("其他连接字串");
}
看到这个代码,肯定很多人都会感冒。嵌套的if ...else...语句确实感到一个“晕”字。当然我们可以IF的同胞兄弟switch。但是无论如何都叫人感觉不爽。根治嵌套的if ...else...语句和switch等多分支之“病”的最有效的秘方就是使用工厂方法模式,通过工厂类与抽象类的关联,并且采用“依赖注入”和“反射”,通过系统外的配置决定实例化哪个访问类。改进一下DBConfig类。

DBConfig类
DBConfig类
using System;

namespace PublisherDB
{
    //ConnectionString、Dll、ClassName均可从系统外获取,如注册表,XML配置文件等
    public class DBConfig
    {
        public static int PooledConnectionCount = 0; //连接数
        public static DBOperator[] ConnectionPool = new DBOperator[2];//连接数组
        public static int CurrentPosition = -1;//当前连接
        public static string ConnectionString//数据库连接字串
        {
            get { return "server=(local);user id=sa;password=123;database=publisher"; }
        }
        public static string Dll//本程序集文件名
        {
            get{ return "PublisherDB.dll";}
        }
        public static string ClassName //数据库访问类名
        {
            get { return "PublisherDB.SqlDBOperator"; }
        }
    }
}


工厂类
using System;
using System.Reflection;

namespace PublisherDB
{
    public class DBOperatorFactory
    {
        public static DBOperator CreateInstance()
        {
            object[] args = { DBConfig.ConnectionString };
           
            DBConfig.CurrentPosition++;
           
            if (DBConfig.PooledConnectionCount == 0)
                DBConfig.ConnectionPool[DBConfig.CurrentPosition] = (DBOperator)Assembly.Load(DBConfig.Dll).CreateInstance(DBConfig.ClassName, false,
                BindingFlags.Default, null, args, null, null);

            if (DBConfig.CurrentPosition == DBConfig.PooledConnectionCount)
                DBConfig.CurrentPosition = 0;

            if (DBConfig.ConnectionPool[DBConfig.CurrentPosition] != null)
                return DBConfig.ConnectionPool[DBConfig.CurrentPosition];

            DBConfig.ConnectionPool[DBConfig.CurrentPosition] = (DBOperator)Assembly.Load(DBConfig.Dll).CreateInstance(DBConfig.ClassName, false,
                BindingFlags.Default, null, args, null, null);

            return DBConfig.ConnectionPool[DBConfig.CurrentPosition];
        }
    }
}
调用代码如下:

DBOperator db=DBOperatorFactory.CreateInstance();
最后,用类图展示一下类之间的关系。

 PublisherDBClassDiagram.JPG
SmartPublisher技术架构
SmartPublisherArchitecture1.JPG


源代码下载地址:SmartPublisher2008-1-10

最新5条评论 查看所有评论
评论内容:请自觉遵守互联网相关政策法规。
用户名: 密码: 匿名 注册
热门文章
随机推荐
About iTtang - 联系方法  - 专题列表 - 友情链接  -  高级搜索   -  帮助中心  -