"类工厂模式"改写SqlHelper

2023-05-16

看到标题您一定很疑惑,23种经典设计模式什么时候多了一个"类工厂模式",稍等,请听我慢慢道来。

实践是检验真理的唯一途径。最近用了"类工厂模式"改写了我公司的SqlHelper类,改写了一大半了,拿出半成品和大家一起讨论。

首先说下我们公司环境:我公司在ABC三地都有工厂,同时都有各自的DB。经过调研,ABC三地的很多网页都有可有整合在一起的地方,我负责整合三地网页。

一开始,没接触设计模式的时候。我的Sql是这样写的:"select * from "+ strSite +".dbo.Table where Id='XXX'".Sql语句中的strSite是从URL中获得的公司别。

这样可以通过strSite来区分ABC工厂的数据库。我是这样调用SqlHelper类的:DBA.GetDataTable("select * from "+ strSite +".dbo.Table where Id='XXX'");

一个Sql中不可能只有一个表,每写一个表,我就要在前面加上"+ strSite +",如果这样整合下去。公用页面的逻辑复杂了,而且在调试Sql语句的时候更是麻烦,经常因为少些后面的架构,或者多写DB的名称,导致系统报错。

知道了错误,就需要从错误中改变,我发现Sql中的strSite只是提供了一种环境,例如,strSite=A的时候,即为在A公司的DB中执行Sql,在B和C公司,同样是执行Sql的环境变了。

那我可不可以传一个参数,在SqlConnection的时候,动态的选择不同的Sql环境。

咱爷们说干就干,于是就有了下面的代码:


 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data.SqlClient;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 public class DBAStore
 9 {
10     private static string AConnection = "A公司连接字符串";
11     private static string BConnection = "B公司连接字符串";
12     private static string CConnection = "C公司连接字符串";
13 
14 
15     public SqlConnection OrderSqlConnection(string strSite)
16     {
17         return GetConnection(strSite);
18     }
19 
20     // 获取SqlConnection方法
21 
22     private static SqlConnection GetConnection(string strSite)
23     {
24         switch (strSite)
25         {
26             case "A":
27                 return new SqlConnection(AConnection);
28             case "B":
29                 return new SqlConnection(BConnection);
30             case "C":
31                 return new SqlConnection(CConnection);
32             default:
33                 return null;
34         }
35     }
36 }  
DBAStore

 1 using System;
 2 using System.Data;
 3 using System.Data.SqlClient;
 4 using System.Configuration;
 5 using System.Collections.Generic;
 6 using System.Web;
 7 using System.Web.Security;
 8 using System.Web.UI;
 9 using System.Web.UI.WebControls;
10 using System.Web.UI.WebControls.WebParts;
11 using System.Web.UI.HtmlControls;
12 using System.Collections;
13 
14 public class DBA
15 {
16     public DBA()
17     {
18         //
19         // TODO: Add constructor logic here
20         //
21     }
22     /// <summary>
23     /// 执行Sql返回DataTable(新版)
24     /// </summary>
25     /// <param name="strSite">公司别</param>
26     /// <param name="strSql">SQLStatement</param>
27     /// <returns></returns>
28     public static DataTable GetDataTable(string strSite, string strSql)
29     {
30         DBAStore dbaStore = new DBAStore();
31         SqlConnection objConn = dbaStore.OrderSqlConnection(strSite);
32         SqlDataAdapter objAdapter = new SqlDataAdapter(strSql, objConn);
33         try
34         {
35             DataSet ds = new DataSet();
36             objAdapter.Fill(ds, "dt");
37             return ds.Tables["dt"];
38         }
39         catch (SqlException e)
40         {
41             //这里面写可以写ErrorLog
42         }
43     }
44 
45 
46 }  
DBA

上面2个类就可以完成我所想的功能,因为用的是Static写的,所以可以直接用,于是就有了下面的Sql语句:"select * from Table where Id='XXX'",如果我想获得A公司的数据,就如下调用:DBA.GetDataTable("A",SqlStatemet);(SqlStatement即为前面黄色背景的Sql语句)。

拿着改写好的SqlHelper,向我师傅炫耀去了,师傅看过之后邹着眉头说,你这样写固然是有好处的,但是你将本来对数据库没有任何意义的公司别传入SqlHelper,增加了耦合度,虽然解决了现在的问题,但是对以后的拓展应该是不好的。(其实静态类就这点不好,实在无法完美支持SqlHelper,如果哪位师兄有好的方法,请一定不要吝啬指导我)

好吧,第一次出师就不利,简单和师傅还有我们经理讨论了下未来SqlHelper的架构方向,一致决定在整合的页面中不再使用静态类去完成Sql语句,转而用工厂模式来写我们的SqlHelper.

在《Head First》中,工厂模式用的是Pizza的例子来诠释的,有一个Pizza来决定如何做Pizza,有一个PizzaStore来决定如何做哪个地区的Pizza.

于是我把SqlHelper的变化部分抽象出来,写一个抽象类SqlStatement,里面有GetConnection(获得不同公司的连接字符串)和Result(获得不同的返回值,例如DataTa或者首行首列等)两种抽象方法,由SqlStatement来决定如何去执行一个Sql,另外写一个DBAStore来决定获得哪个公司的连接字符串。

代码如下:

类似于Pizza的抽象超类,实现如何执行Sql。DBAStore,功能和类名一样,抽象用来实现,决定获得哪个公司的连接字符串。


 1     public abstract class SqlStatement
 2     {
 3         public abstract SqlConnection GetSqlConnection();
 4 
 5         public abstract object Result(string strSql);
 6         //{
 7         //    //SqlConnection sqlConnection = GetSqlConnection(strSite);
 8         //    //return SqlCommand(strSql,get);
 9         //}
10     }  
SqlStatement

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data.SqlClient;
 4 using System.Linq;
 5 using System.Text;
 6 using System.Threading.Tasks;
 7 
 8 namespace DBHelp
 9 {
10     public abstract class DBAStore
11     {
12         public SqlConnection OrderDBA(string strSite)
13         {
14             SqlConnection objConn;
15             objConn = CreateDBA(strSite);
16             return objConn;
17         }
18         public abstract SqlConnection CreateDBA(string strSite);
19     }
20     public class OA : DBAStore
21     {
22         private string _aConnection= "A公司连接字符串";
23         private string _bConnection = "B公司连接字符串";
24         private string _cConnection = "C公司连接字符串";
25 
26 
27 
28         public string CConnection
29         {
30             get { return _cConnection; }
31             set { _cConnection = value; }
32         }
33 
34         public string BConnection
35         {
36             get { return _bConnection; }
37             set { _bConnection = value; }
38         }
39 
40 
41         public string AConnection
42         {
43             get { return _aConnection; }
44             set { _aConnection = value; }
45         }
46 
47         public override SqlConnection CreateDBA(string strSite)
48         {
49             switch (strSite)
50             {
51                 case "A":
52                     return new SqlConnection(_aConnection);
53                 case "B":
54                     return new SqlConnection(_bConnection);
55                 case "C":
56                     return new SqlConnection(_cConnection);
57                 default:
58                     return null;
59             }
60         }
61     }
62 }  
DBAStore

GetDataTable类,继承于SqlStatement,返回一个DataTable类型的dt


 1 using System;
 2 using System.Collections.Generic;
 3 using System.Data;
 4 using System.Data.SqlClient;
 5 using System.Linq;
 6 using System.Text;
 7 using System.Threading.Tasks;
 8 
 9 namespace DBHelp
10 {
11     public class GetDataTable:SqlStatement
12     {
13         private string _strSite;
14 
15         public GetDataTable(string strSite)
16         {
17             _strSite = strSite;
18         }
19 
20         public override SqlConnection GetSqlConnection()
21         {
22             DBAStore dbaStore = new OA();
23             SqlConnection sqlConnection = dbaStore.OrderDBA(_strSite);
24             return sqlConnection;
25         }
26 
27         public override object Result(string strSql)
28         {
29             SqlConnection sqlConnection = GetSqlConnection();
30             SqlDataAdapter sqlDataAdapter = new SqlDataAdapter(strSql, sqlConnection);
31             sqlConnection.Open();
32             try
33             {
34                 DataSet ds = new DataSet();
35                 sqlDataAdapter.Fill(ds, "dt");
36                 return ds.Tables["dt"];
37             }
38             catch
39             {
40                 return null;
41             }
42             finally
43             {
44                 sqlConnection.Close();
45             }
46         }
47     }
48 }  
GetDataTable

通过以上三个类,我们就可以通过New实例的方式来执行Sql,返回需要的数值。

SqlStatement GetDataTable = new GetDataTable("A");//将DB环境切换到A公司,就像在SQL SERVER Management Studio中使用:"USE A"一样。
GetDataTable.Result("select Site from Table where Id in ('XXX','OOO')");//在A公司环境下执行前面黄色背景的Sql语句。

如果您需要返回一个Bool值去判断是否执行插入或者删除语句,那么就新建一个ExecSql,继承于SqlStatement,更改相应参数就可以获得是否执行成功。

因为代码比较容易写,我就不再提供相应的类了,您可以自己试试,真的非常简单。

 

但是,这时候问题又出来了,每次我使用不同方法执行Sql,或返回Bool值,或返回一个DataTable值,每次都得New一次,实在非常繁琐了,能不能像以前那样,直接用静态方法,实现类似DBA("A").GetDataTable("Sql语句")或者DBA("B").ExecSql("Sql语句")呢,亲爱的小伙伴,我也在朝这个方向努力,希望能和大家一起探讨如何写更简单的SqlHelper。

 

文章写到最后,我来解释下,为什么我要用"类工厂模式"来形容个写的这个SqlHelper呢,聪明的小伙伴,您有没有发现,我在写DBAStore类的时候,在创建一个连接字符串的时候,用了一个Switch来返回不同公司的连接字符串,这和《Head First》中创建不同的确Pizza店返回的是Pizza类型的值,而我的DBAStore中没有更过度设计的返回一个SqlStatement类型。所以这点和工厂模式有点差异,为了纪念第一次理解工厂模式,就让我用这个"类工厂模式"给自己庆贺吧。

 

写在最后:

因为时间比较晚了,也准备将博文发给同事,让他们帮忙点赞,UML图,暂时就不提供了,后续会提供。

可能您会问,为什么不提供一个完整的SqlHelper方法给大家使用?我的解释是,我其实也没有完全做到我梦想的方式。同时每天等QQ邮箱的时候,能看到有人给我上一篇文章评论的话语,感觉倍受鼓舞,如果长时间不更新博文,他们以为我失踪了,或者以为我放弃了程序员这个行业,为了他们,我选择将我这个半成品公布出来,让大家使用。

关于代码能否使用:这个您可以放心,我是经过调试的,并且用在我们公司的正式环境的,是可以使用的,只是为了保密和安全性考虑,我截取的时候,可能会有误差,如果您Copy了代码,但是无法使用,可以联系我索取完整代码。

关于程序员这条路:之前阅读过李开复的自传《让世界因你而不同》,真的被谷歌、微软等IT巨头的工作环境还有他们所写的酷炫的代码所吸引。回到现实,我们毕业于最低流大学,大学的时候压根不会去敲代码。即使院长希望我们能在4年中敲出20000行代码,实际上我们压根连200行都没敲出来。毕业后,匆匆忙忙找个培训公司培训,然后去工作,拖控件,重复性工作,长时间加班,一切的实现压碎了我们的理想。但我想对您和我自己说,人应该有梦想,应该让世界因为我们的存在而有一点的的确确的不同。希望您和我在看到这句话的时候,能摈弃以前的借口,多学习学习,成长为一名合格的程序员,而不是码农、码畜。

 

话有点多,有点啰嗦,而且语言不清晰,逻辑混乱,请您见谅。

转载于:https://www.cnblogs.com/SunnyZhu/p/3854454.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

"类工厂模式"改写SqlHelper 的相关文章

  • Python3.7安装cv2踩过的坑

    首先说下载cv2模块 xff1a 安装cv2模块不能直接用命令pip install cv2安装 xff0c 要用pip install opencv python安装 xff0c 当然可能默认下载的模块跟你的Python环境不匹配 xff
  • 【docker】查看docker容器或镜像的详细信息命令,查看docker中正在运行的容器的挂载位置...

    命令 xff1a docker inspect f257d69e0035 格式 xff1a docker inspect 容积或镜像ID 首先 xff0c docker ps获取简要信息 然后输入命令docker inspect f257d
  • C项目实践之通讯录管理案例

    1 功能需求分析 通讯录管理案例主要实现对联系人的信息进行添加 显示 查找 删除 更新和保存功能 主要功能需求描述如下 xff1a xff08 1 xff09 系统主控平台 xff1a 充许用户选择想要进行的操作 xff0c 包括添加联系人
  • 开源自主导航小车MickX4(十)总结

    开源自主导航小车MickX4 xff08 十 xff09 总结 1 博客回顾2 存在问题3 学习建议4 后续计划 在 开源自主导航小车MickX4 这个系列教程中 xff0c 我们一共分为了十个博客部分进行了讲解差速小车的导航 由于一些的原
  • iOS 什么是函数式编程

    前言 xff1a 当前只做理解性的常规背书 xff0c 根据不断深入学习会不断丰富解读内容 xff0c 欢迎评论提意见 函数式编程 xff1a Functional Programming 1 基本解释 xff1a 函数式编程 是一种思维模
  • MVC笔记 MVC注意事项及优化

    一 学习MVC注意事项 1 了解不同的项目类型 从ASP NET 2 0开始 xff0c vs针对网站开发区分了两种项目类型 xff0c 一种是 39 项目 39 xff08 Website Project xff09 另一种是 39 网址
  • 微软:新Windows设备需要默认支持TPM 2.0安全功能

    在Windows 10系统中微软已经做出大量调整来提升安全性能 xff0c 而现在微软进一步提升运行最新操作系统设备的安全等级 自今年夏天开始 xff0c 微软表示需要所有Windows 10设备都默认支持TPM 2 0 可信任安全平台模组
  • 令牌桶算法限流

    限流 限流是对某一时间窗口内的请求数进行限制 xff0c 保持系统的可用性和稳定性 xff0c 防止因流量暴增而导致的系统运行缓慢或宕机 常用的限流算法有令牌桶和和漏桶 xff0c 而Google开源项目Guava中的RateLimiter
  • 关机一直显示正在关闭服务器,电脑关机后,显示正在关机,但等半天也关不了 怎么办...

    电脑关机后 xff0c 显示正在关机 xff0c 但等半天也关不了 怎么办以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 xff0c 让我们赶快一起来看一下吧 xff01 电脑关机后 xf
  • 一只老鸟嵌入式工程师的血泪史!

    作为一名在嵌入式行业摸爬滚打许久的老鸟 xff0c 回想自己的经历之路 xff0c 那么漫长可又仿佛近在眼前 随着学生的日益增多 xff0c 偶尔之间 xff0c 会想起自己曾经的一个经历 此文仅献给那些刚刚踏上硬件之路和还在徘徊的同学们
  • 程序员的“菜鸟心态综合症”

    第3章 程序员的 菜鸟心态综合症 清华大学出版社 Java程序员 xff0c 上班那点事儿 作者 xff1a 钟声 第3章部分节选 人的一生会遇到很多挫折 xff0c 尤其是我们刚刚参加工作初期的年轻人 这个人生阶段往往会出现各种各样的处世
  • sc.textFile("file:///home/spark/data.txt") Input path does not exist解决方法——submit 加参数 --master local...

    use this val data 61 sc textFile 34 home spark data txt 34 this should work and set master as local Input path does not
  • mongodb查询数据库中某个字段中的值包含某个字符串的方法

    正则表达式最能解决 xff1a 例如 xff1a db getCollection 39 news 39 find 39 content 39 120 77 215 34 9999 这里主要是注意正则表达式要写对 xff0c 该转义的注意转
  • MATLAB 求两个矩阵的 欧氏距离

    欧式距离定义 xff1a 欧式距离公式有如下几种表示方法 xff1a MATLAB 求两个矩阵的 欧氏距离 xff1a 如果定义两个矩阵分别为a b 则定义c 61 a b 2 所求距离d 61 sqrt sum c
  • Vmware虚拟机磁盘空间不足

    Vmware虚拟机清理磁盘空间 遇到一个问题就是虚拟机中的磁盘空间越来越小 xff0c 即使把文件删除以后 xff0c 磁盘空间还是无法释放 这主要是vmware中的缓存没有清除 在使用vmware虚拟机的时候 xff0c 经常会在主机和虚
  • 技术面试感觉什么都会,面试官一问回答不上来怎么办?

    又到了一年金三银四 xff0c 回想到很多年前我刚参加工作时的面试经历 xff0c 那时都是呆呆地等着面试官问问题 xff0c 被问到一些自己并不熟悉的问题时要不就是思考半天也切不中要点 xff0c 要不就只能无奈地回答并不清楚了 其实不管
  • 强化学习遭遇瓶颈!分层RL将成为突破的希望

    本文作者是法国里尔大学Inria SequeL团队的博士生 xff0c Yannis Flet Berliac xff0c 他在本文中对分层强化学习 xff08 HRL xff09 的研究进行了总结 xff0c 文章首先回顾了强化学习 xf
  • 如何免费下载百度文库文章的三种方法

    百度文库中的资源很丰富 xff0c 但那里的文章不能复制 xff0c 而且有的要下载币 给 大家总结下免费下载复制百度文库的三种方法 第一种 利用百度快照 我们在百度文库中找到自己想要的文章后 xff0c 直接把那篇文章的地址复制 xff0
  • 434个H5游戏源码

    各种类型HTML5游戏 xff0c 界面和JS均可供项目参考 下面是下载地址 转载于 https blog 51cto com 12130120 2374590
  • iOS 左右滑动 手势 响应方法

    1 64 property nonatomic strong UISwipeGestureRecognizer leftSwipeGestureRecognizer 64 property nonatomic strong UISwipeG

随机推荐

  • 一道c语言编程题

    一道c语言编程题 将一个5 5的矩阵中最大的元素放在中心 xff0c 四个角分别放四个最小的元素 xff08 顺序从左到右 xff0c 从上到下顺序依次从小到大存放 xff09 xff0c 写一函数实现之 xff0c 用main函数调用 i
  • print(1,2,3,sep=':')的输出结果是?

    print 1 2 3 sep 61 39 39 1 2 3 第一个参数 要打印的值 第二个参数sep表示要打印多个值时 各值的分割方式 默认空格 第三个参数end表示结尾的方式 默认 n 转载于 https www cnblogs com
  • S3. Android 消息推送

    概要 消息推送 转载于 https www cnblogs com zlxyt p 11133181 html
  • Android camera2 回调imagereader 从Image拿到YUV数据转化成RGB,生成bitmap并保存

    ImageUtil java import android graphics ImageFormat import android media Image import android os Build import android sup
  • C语言中字符串结束符'\0'

    本质 39 0 39 就是8位的00000000 xff0c 因为字符类型中并没有对应的这个字符 xff0c 所以这么写 39 0 39 就是 字符串结束标志 39 0 39 是转义字符 xff0c 意思是告诉编译器 xff0c 这不是字符
  • SLAM中双目三角化

    双目三角化 形式1 xff1a 在等式左边同时乘 x 1 x 1 x 1 和
  • 用手机对电脑进行远程关机

    PS 本人一月份写的文章 xff0c 贴在这里 昨天真是奔波的一天 xff0c 中午烤肉逛街下午寿司看电影 xff08 陪老婆 xff09 今天中午又是麻辣诱惑 额 xff0c 不争气的肠胃果然导致我拉肚子了 不过 xff0c 话说昨天下午
  • 程序员到底是一个什么职业?

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 程序员首先是雇员 然后是工程师 xff1b 比起创造力 xff0c 工程能力对这个职位更为重要 为什么有人在技术造神 大家应该已经感受到 xff0c 技术圈这两年已经和娱乐
  • android 清理内存杀死service,关于Service常驻内存不被清理的解决方法.

    众所周知 Service是跑后台的 但是有些Rom厂商把一键清理做的真是太好用了 以至于一键清理变成了一种习惯 Service已经变的不再是Service了 那为什么像诸如360 微信 QQ 却可以傍山傍水 哦 用错词了 大家懂的 言归正传
  • 自主做一个类似于微博的项目(计划篇)

    项目名称 xff1a archou微博 项目架构 xff1a B S架构 项目开发语言 xff1a java jquery html hql 开发框架 xff1a spring mvc hibernate 开发平台 xff1a window
  • [工作记录] 点云线特征提取

    概述 目前的点云线特征提取方法可以分为 xff1a 1 基于面片patch的线特征提取 xff0c 主要可以提取交线 xff0c 边缘线 这类方法首先都是要提取面 xff0c 然后对每个面对象提取 又可以分为 xff1a 基于图像的提取 x
  • Javascript闭包:从理论到实现,[[Scopes]]的每一根毛都看得清清楚楚

    昨天我写到 所有Javascript函数都是闭包 xff0c 有些同学表示还是接受不能 我好好的一个函数 xff0c 怎么就成闭包了 xff1f 那么 xff0c 让我们来探究一下 xff0c Chrome xff08 V8 xff09 到
  • mysql5.7安装审计插件libaudit_plugin.so

    1 下载插件 https bintray com mcafee mysql audit plugin release 1 1 7 805 files 2 解压插件复制到mysql lib库插件目录下 xff1a unzip audit pl
  • 通过jdbc连接hive报java.sql.SQLException: Method not supported问题

    今天尝试通过jdbc连接hive xff0c JDBC直接连接是正常成功的 xff0c 实例 xff1a import java sql Connection import java sql DriverManager import jav
  • DHCP介绍及H3C配置DHCP

    1 DHCP引入 1 简介 DHCP xff08 动态主机设置协议 xff09 是一个局域网的网络协议 xff0c 使用UDP协议工作 xff0c 主要作用是集中的管理 分配IP地址 xff0c 使网络环境中的主机动态的获得IP地址 Gat
  • centos7-内核版本降级

    环境介绍 线上环境运行centos 内核版本规定为 xff1a CentOS Linux release 7 3 1611 Core 查看内核版本参考命令 xff1a root 64 localhost cat etc redhat rel
  • SLAM中多目三角化

    多目三角化 1 闭式求解1 1 DLT 最小二乘方法求解1 2 最小化3D距离 2 构建优化方法求解3 构建高斯深度滤波器 LSD SLAM4 构建Beta分布滤波器 SVO5 EKF SLAM参考资料 在能实现双目计算特征点的深度基础上
  • 微软操作系统 Windows Server 2012 R2 官方原版镜像

    微软操作系统 Windows Server 2012 R2 官方原版镜像 Windows Server 2012 R2 是由微软公司 xff08 Microsoft xff09 设计开发的新一代的服务器专属操作系统 xff0c 其核心版本号
  • 最近很忙,也很累,忙里偷闲,尝试了下apache solr的安装

    最近很忙 xff0c 也很累 xff0c 忙里偷闲 xff0c 尝试了下apache solr的安装 第一次接触java的 xff0c 就和初次安装NET一样 部署开发环境折腾来折腾去 几经波折总算成功了 分享下个人安装的过程 xff1a
  • "类工厂模式"改写SqlHelper

    看到标题您一定很疑惑 xff0c 23种经典设计模式什么时候多了一个 34 类工厂模式 34 稍等 xff0c 请听我慢慢道来 实践是检验真理的唯一途径 最近用了 34 类工厂模式 34 改写了我公司的SqlHelper类 xff0c 改写