其他数据库访问类
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();
最后,用类图展示一下类之间的关系。
SmartPublisher技术架构
源代码下载地址:SmartPublisher2008-1-10
RSS订阅






收 藏
推 荐