c 工厂模式与mysql链接_工厂模式连接数据库
在项目中通常可能会使用不同的数据源,可能是SQL Server也可能是ACCESS或者是Oracle,那么如何保证在使用不同数据源的时候,使项目代码更改的代价最小呢?
对,使用工厂模式.在Net1.1的时候,这需要项目实施者自己来完成.在Net2.0中,MS已经新增了几个用于实施工厂模式的类库.
首先我现在应用程序当前目录下新建Databases目录,再新建一个Access数据库与Sqlserver数据库
其中这2个数据库的结构都是一样的,都包含一个SampleData表,有ID,与IntegerValue字段
然后回到VS中新建一个WinForm 项目,然后编辑App.Config文件如下:
xml version="1.0" encoding="utf-8" ?>
这里记录着实施项目中可能会用到的数据库连接信息
providerName 记录数据驱动
connectionString 数据源连接字符串 |DataDirectory|指应用程序当前目录-->
这里使用SqlServer2005直接在应用程序中附加数据库 -->
connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Databases\MyData.mdf;Integrated Security=True;User Instance=True" />
connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Databases\MyData.mdb;Persist Security Info=True" />
connectionStrings>
configuration>
然后在主窗体中的Button事件中编写如下代码
private void getDataButton_Click(object sender, EventArgs e)
{
try
{
//创建一个新的StopWatch来监视连接性能[Net2.0新增]
Stopwatch myWatch = new Stopwatch();
// 开始计算connection and retrieval of data所花费的时间
myWatch.Start();
// 选择要使用的数据源
string strDataSource="MS Access";
// 根据选者的数据源获得连接字符串的配置对象
ConnectionStringSettings objConnectionSettings = ConfigurationManager.ConnectionStrings[strDataSource];
// 通过配置文件创建数据库驱动工厂的实例
DbProviderFactory objProviderFactory = DbProviderFactories.GetFactory(objConnectionSettings.ProviderName);
// 通过数据库驱动工厂创建DBConnection实例
using (DbConnection objConnection = objProviderFactory.CreateConnection())
{
// 从 objConnectionSettings 中获取连接字符串
objConnection.ConnectionString = objConnectionSettings.ConnectionString;
// 打开 connection
objConnection.Open();
// 通过数据驱动工厂创建 数据适配器和 Command
DbDataAdapter myAdapter = objProviderFactory.CreateDataAdapter();
DbCommand myCommand = objProviderFactory.CreateCommand();
string myQuery = "SELECT * FROM SampleData";
DataSet myDataSet = new DataSet();
myCommand.Connection = objConnection;
myCommand.CommandText = myQuery;
myAdapter.SelectCommand = myCommand;
myAdapter.Fill(myDataSet);
displayDataGridView.DataSource = myDataSet.Tables[0];
// 停止StopWatch来查看连接和返回数据所花费的时间
myWatch.Stop();
elapsedTimeTextLabel.Text = "消耗时间: " myWatch.ElapsedMilliseconds.ToString() " ms";
providerLabel.Text = "数据驱动: " objConnectionSettings.ProviderName.ToString();
connectionStringLabel.Text = objConnectionSettings.ConnectionString.ToString();
}
}
catch
{
MessageBox.Show("出现错误.", "Alert");
}
}
}
这样,只需要更改strDataSource就可以使用不同的数据源,而且整个项目都不需要为不同的数据库而烦恼
=====================================================================================================
使用设计模式构建通用数据库访问类
在应用程序的设计中,数据库的访问是非常重要的,我们通常需要将对数据库的访问集中起来,以保证良好的封装性和可维护性。在.Net中,数据库的访问,对于微软自家的SqlServer和其他数据库(支持OleDb),采用不同的访问方法,这些类分别分布于System.Data.SqlClient和System.Data.OleDb名称空间中。微软后来又推出了专门用于访问Oracle数据库的类库。我们希望在编写应用系统的时候,不因这么多类的不同而受到影响,能够尽量做到数据库无关,当后台数据库发生变更的时候,不需要更改客户端的代码。
这就需要我们在实际开发过程中将这些数据库访问类再作一次封装。经过这样的封装,不仅可以达到上述的目标,还可以减少操作数据库的步骤,减少代码编写量。在这个方面,微软为我们提供了Application Block,但是,可惜的是目前只支持Sql Server。这里,介绍一种在实际应用中得到了非常好的效果的实作策略——笔者编写的Websharp框架中的数据访问结构。Factory设计模式是使用的主要方法。
我们先来看看Factory的含义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。我们这里可能会处理对多种数据库的操作,因此,需要首先定义一个操纵数据库的接口,然后,根据数据库的不同,由类工厂决定实例化哪个类。
下面,我们首先来定义这个访问接口。为了方便说明问题,我们在这里只列出了比较少的方法,其他的方法是很容易参照添加的。
public interface DataAccess
{
DatabaseType DatabaseType{get;} //数据库类型
IDbConnection DbConnection{get;} //得到数据库连接
void Open(); //打开数据库连接
void Close(); //关闭数据库连接
IDbTransaction BeginTransaction(); //开始一个事务
int ExecuteNonQuery(string commandText); //执行Sql语句
DataSet ExecuteDataset(string commandText);//执行Sql,返回DataSet
}
因为,DataAccess的具体实现类有一些共同的方法,所以,先从DataAccess实现一个抽象的AbstractDataAccess类,包含一些公用方法。然后,我们分别为Sql Server、Oracle和OleDb数据库编写三个数据访问的具体实现类:
public sealed class MSSqlDataAccess : AbstractDataAccess
{
……//具体实现代码。
}
public class OleDbDataAccess : AbstractDataAccess
{
……//具体实现代码。
}
public class OracleDataAccess : AbstractDataAccess
{
……//具体实现代码。
}
现在我们已经完成了所要的功能,下面,我们需要创建一个Factory类,来实现自动数据库切换的管理。这个类很简单,主要的功能就是根据数据库类型,返回适当的数据库操纵类。
public sealed class DataAccessFactory
{
private DataAccessFactory(){}
private static PersistenceProperty defaultPersistenceProperty;
public static PersistenceProperty DefaultPersistenceProperty
{
get{return defaultPersistenceProperty;}
set{defaultPersistenceProperty=value;}
}
public static DataAccess CreateDataAccess(PersistenceProperty pp)
{
DataAccess dataAccess;
switch(pp.DatabaseType)
{
case(DatabaseType.MSSQLServer):
dataAccess = new MSSqlDataAccess(pp.ConnectionString);
break;
case(DatabaseType.Oracle):
dataAccess = new OracleDataAccess(pp.ConnectionString);
break;
case(DatabaseType.OleDBSupported):
dataAccess = new OleDbDataAccess(pp.ConnectionString);
break;
default:
dataAccess=new MSSqlDataAccess(pp.ConnectionString);
break;
}
return dataAccess;
}
public static DataAccess CreateDataAccess()
{
return CreateDataAccess(defaultPersistenceProperty);
}
}
好了,现在,一切都完成了,客户端在代码调用的时候,可能就是采用如下形式:
PersistenceProperty pp = new PersistenceProperty();
pp.ConnectionString = "server=127.0.0.1;uid=sa;pwd=;database=Northwind;";
pp.DatabaseType = DatabaseType. MSSQLServer;
pp.UserID = “sa”;
pp.Password = “”;
DataAccess db= DataAccessFactory.CreateDataAccess(pp)
db.Open();
……//db.需要的操作
db.Close();
或者,如果事先设定了DataAccessFactory的DefaultPersistenceProperty属性,可以直接使用
DataAccess db= DataAccessFactory.CreateDataAccess()
方法创建DataAccess实例。
当数据库发生变化的时候,只需要修改PersistenceProperty的值,客户端不会感觉到变化,也不用去关心。这样,实现了良好的封装性。当然,前提是,你在编写程序的时候,没有用到特定数据库的特性,例如,Sql Server的专用函数。
=================================================================================
数据库访问一般有不同中数据库,比如Oracle,Sqlserver,Mysql等。 怎样使得程序有一定的通用性。我们可以使用工厂模式来实现。具体代码如下:
1 抽象类
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
namespace HHSCInfor.App_Code.Database
...{
///
/// Summary description for absDB
///
public abstract class AbsDB
...{
public AbsDB()
...{
//
// TODO: Add constructor logic here
//
}
//得到数据库连接
public abstract IDbConnection Connection ...{ get;}
//打开数据库连接
public abstract void Open();
//关闭数据库连接
public abstract void Close();
//开始一个事务
public abstract void BeginTrans();
//提交一个事务
public abstract void CommitTrans();
//回滚一个事务
public abstract void RollbackTrans();
//执行Sql语句,没有返回值
public abstract void ExeSql(string strSql, string[] strParams, object[] objValues);
//执行Sql,返回DataSet
public abstract DataSet ExeSqlForDataSet(string QueryString);
}
}
2 Oracle连接的实例化
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OracleClient;
namespace HHSCInfor.App_Code.Database
...{
///
/// Summary description for OracleDB
///
internal class OracleDB : AbsDB
...{
///
/// 数据库连接状态表示
///
private string OpenFlag = "OPEN";
public OracleDB()
...{
}
//数据库连接
private OracleConnection conn;
//事务处理类
private OracleTransaction trans;
//指示当前是否正处于事务中
private bool inTransactionFlag = false;
public override IDbConnection Connection
...{
get ...{ return this.conn; }
}
public OracleDB(string strConnection)
...{
this.conn = new OracleConnection(strConnection);
}
public override void Open()
...{
if (conn.State.ToString().ToUpper() != OpenFlag)
this.conn.Open();
}
public override void Close()
...{
if (conn.State.ToString().ToUpper() == OpenFlag)
this.conn.Close();
}
public override void BeginTrans()
...{
trans = conn.BeginTransaction();
inTransactionFlag = true;
}
public override void CommitTrans()
...{
trans.Commit();
inTransactionFlag = false;
}
public override void RollbackTrans()
...{
trans.Rollback();
inTransactionFlag = false;
}
public override void ExeSql(string strSql, string[] strParams, object[] strValues)
...{
//创建命令
OracleCommand cmd = new OracleCommand();
//设置连接
cmd.Connection=this.conn ;
//比较参数个数和参数值数组的长度是否匹配
if ((strParams != null) && (strParams.Length != strValues.Length))
...{
throw new Exception("查询参数和值不对应!");
}
cmd.CommandText = strSql;
if (strParams != null)
...{
for (int i = 0; i
...{
cmd.Parameters.Add(strParams[i], strValues[i]);
}
}
//执行SQL语句
cmd.ExecuteNonQuery();
}
///
/// 执行数据库查询并将结果用数据集(DataSet)的形式返回
///
/// SQL语句
///
public override DataSet ExeSqlForDataSet(string QueryString)
...{
//创建命令
OracleCommand cmd = new OracleCommand();
//设置连接
cmd.Connection = this.conn;
//传入查询语句
cmd.CommandText = QueryString;
//创建数据集
DataSet ds = new DataSet();
//创建适配器
OracleDataAdapter ad = new OracleDataAdapter();
//适配器命令
ad.SelectCommand = cmd;
//填充到数据集(DataSet)
ad.Fill(ds);
//返回结果数据集
return ds;
}
}
}
3 SqlServer的实例化(自己对照上面写个,我也没写。^_^)
4 根据不同的string连接来创建不同的实例。
web.config中设置共用连接:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data.OracleClient;
namespace HHSCInfor.App_Code.Database
...{
///
/// Summary description for DBConn
///
public class DBConn
...{
public DBConn()
...{
}
///
/// 根据不同的字符串连接来使用不同的处理程序。
/// 工厂方法应用(可以根据不同的strConnection创建不同的连接)。
///
/// 数据库连接字符串
///
public static AbsDB GetDBConn()
...{
// 只有一个Oracle连接时使用,如果有多个,在此添加。在Web.Config里配置。
string strConnection = System.Configuration.ConfigurationManager.AppSettings["DBConnStr"];
// 创建OracleDB连接对象
return new OracleDB(strConnection);
///比如有sqlserver添加如下
///if(strConnection=?)
///{
/// return(SqlServerDB(strConnection));
///}
}
}
}
5 测试程序:
AbsDB conn = DBConn.GetDBConn();
DataSet ds = conn.ExeSqlForDataSet("select * from sysFunction");
this.Label1.Text = ds.Tables[0].Rows[2]["功能名称"].ToString();
conn.Close();
我的测试通过。
c 工厂模式与mysql链接_工厂模式连接数据库相关推荐
- 工厂模式三部曲之二_工厂模式
自<工厂模式三部曲之一_简单工厂模式>之后,貌似已经很久没有继续这个三部曲了,所以抽点时间把后两篇给补上吧.首先回顾下简单工厂模式的主要内容:简单工厂模式就是实质就是专门定义了一个工厂类, ...
- go mysql连接_使用 Go 连接数据库
简介 在 Go 中连接数据库的方式有很多, 这里我们选择使用 ORM 的方式, 也就不用写原生的 SQL 语句了. Go 的 ORM 库也有很多, 这里选择了 gorm. 安装 gorm go get ...
- 客户端连接不上mysql数据库_客户端无法连接数据库的小问题
最近碰到了一个比较奇怪的数据库连接问题.问题的起因是做一个数据整合的时候,把服务器B的防火墙信息都拷贝到了服务器A,迁移的过程都很顺利,是一套开发测试环境,迁移完成之后,从应用的反馈来说都没有发现问题 ...
- 苹果手机变成耳机模式怎么调回来_苹果耳机模式怎么调回来
有的时候手机会无缘无故进入耳机模式,具体表现就是已经把耳机从手机的耳机孔中拔出,但是手机依旧不会使用外放喇叭播放,在控制中心依旧显示有耳机的插入状态,那么苹果耳机模式怎么调回来呢?今天给大家详细介绍一 ...
- 创建对象_工厂方法(Factory Method)模式 与 静态工厂方法
工厂方法模式: 定义:为创建对象定义一个接口,让子类决定实例化哪个类.工厂方法让一个类的实例化延迟至子类. 应用场景: 客户类不关心使用哪个具体类,只关心该接口所提供的功能: 创建过程比较复杂,例如需 ...
- 工厂方法模式_工厂方法模式
工厂方法模式是简单工厂模式的升级版,简单工厂模式不符合设计模式的原则(即:单一职责,开闭原则) 优点: 职责明确,扩展方便 缺点:需要创建多个工厂 实现步骤: 1.将工厂通用方法抽取接口 (例如:IF ...
- python工厂模式 简书_工厂模式
什么是工厂设计模式? 定义一个用于创建对象的接口,让子类决定将哪一个类实例化,专门用来生产对象.在java中,万物皆对象,这些对象都需要创建,如果创建的时候直接new该对象,就会对该对象耦合严重,假如 ...
- JAVA设计模式是个什么玩意儿_00_工厂模式家族准备篇_简单工厂模式
1. 前言 又叫静态工厂方法(Static Factory Method)模式. 它并不是GoF那23种设计模式之一. 简单工厂模式是工厂模式家族中最简单实用的模式. 虽然很简单,但它是学习工厂方法模 ...
- 工厂设计模式解决什么问题_使用工厂模式解决设计问题
工厂设计模式解决什么问题 工厂设计模式是面向对象环境中最常用的模式之一. 再次来自"创意设计"模式类别,即有关对象创建的所有信息. 在某些情况下,对象的创建很复杂,可能需要某种程度 ...
最新文章
- 剑指offer:面试题29. 顺时针打印矩阵
- 写给Linux系统运维的朋友
- python 判断字母大小写
- Matlab GUI 设计(4):不同控件之间的数据传递
- mos管结电容等效模型_MOS管硬开关震荡分析“新能源汽车与电力电子技术”系列之十九...
- AttributeError: module ‘tensorflow‘ has no attribute ‘placeholder‘
- RequestBody注解
- Jerry的SAP Kyma和Kubernetes讲座的幻灯片分享
- jsb调用java_在JS代码中使用反射调用java代码注意事项(附webview使用方法)(转)...
- [蓝桥杯2017决赛]分考场、OpenJudge:分成互质数
- emacs 入门教程,菜单汉化,配置文件等杂乱文章
- C#LeetCode刷题之#771-宝石与石头(Jewels and Stones)
- [Winform]只允许运行一个exe,如果已运行则将窗口置前
- stringGrids 部分只读
- SQL SERVER 2005自动备份
- 一文看懂:边缘计算究竟是什么?为何潜力无限?(下)
- 回来bool的函数无return时返回true还是false
- linkedin 爬虫
- 刷机后IMEI丢失如何能刷回来
- 2021-06-24
热门文章
- 智慧旅游建设智能化景区管理系统方案
- OpenStack Victoria搭建(一)简介
- 2020 ICPC沈阳站-D,H
- 大学计算机应用基础的简介,大学计算机应用基础资料
- easyUI之增加删除与批量删除
- 告别2017,拥抱2018!
- 阅读《SentiLARE: Sentiment-Aware Language Representation Learning with Linguistic Knowledge》
- ipad计算机弹音乐,iPad下的音乐创作工具,Korg发布ELECTRIBE Wave波表音乐创作工具...
- 【LabVIEW小技巧】LabVIEW文本框显示VI名称
- 前端基础 Web网页标准