个人重构的时候,虽说都用上了sqlHelper,但是不认识它的前世今生,所有总感觉很突兀。看牛腩的时候,才恍然大悟。SQLHelper 从名字就能知道,它是和数据库有关系的,并且能帮助到数据库。这样一想,当再理解到“SQLHelper 用于简化你重复的去写那些数据库连接(SqlConnection),SqlCommand,SqlDataReader等等。SqlHelper 封装过后通常是只需要给方法传入一些参数如数据库连接字符串,SQL参数等,就可以访问数据库。”我们就很清楚的懂得他的作用。
今天我们仅仅以一个类来大致看一看SQLHelper 到底是怎么有不同的数据库操作变化来的。
先看一下最原始的一个查询是这样的。
using System.Data;//添加引用 using System.data.SqlClient;//添加引用 namespace DAL { public class SQLHelper { public int Query() { //①定义数据库连接字符串 string connStr=@"server=Madan\SQL;database=mewssystem;uid=sa;pwd=123456"; //②传入数据库的连接字符串 固定语句 SqlConnection conn=new SqlConnection(connStr); //③ 打开 conn.open //④数据库语句 变化语句 string sql="insert into category(name) value('提高班')"; //⑤命令执行对象 需要sql语句和conn命令 固定语句 SqlCommand cmd=new SqlCommand(sql,conn); //⑥执行 返回int 固定语句 int res=cmd.ExecuteNonQuery(); //⑦关闭连接 固定语句 conn.Close(); return res; } } }
不管我们写多少个查询类,都会发现,上面的步骤都是固定的。而会出现变化的只有两个地方,一是连接数据库的登陆用户和密码是会变化的。二是,不同的查询内容导致具体的查询语句不同。所以为了封装变化,我们将变化的部分拿了出来。也将公共的部分进行了提炼。
看了下面的代码我们就知道了不变的部分是怎么提炼的,变化的部分是怎么封装的。直接看代码
<span style="font-family:KaiTi_GB2312;font-size:18px;">using System.Data.SqlClient;//添加引用 using System.Configuration;//添加引用 namespace DAL { public class SQLHelper { //提出常用 private SqlConnection conn = null; private SqlCommand cmd = null; private SqlDataReader sdr = null; public SQLHelper()//初始化构造函数 { string connStr = ConfigurationManager.ConnectionStrings["connStr"].ConnectionString;//②web.config中已经设置好的 connStr 为连接语句 此句为传出连接语句 conn = new SqlConnection(connStr); } // 打开连接的方法 private SqlConnection GetConn() { if (conn.State == ConnectionState.Closed) { conn.Open(); } return conn; } public int ExecuteNonQuery(string sql) { int res; try { cmd = new SqlCommand(sql, GetConn());//③⑤调用上面的方法 打开连接 并传入SQL语句 res = cmd.ExecuteNonQuery();//⑥ 执行 } catch (Exception ex) { throw ex; } finally { if (conn.State == ConnectionState.Open) { conn.Close();//⑦ 关闭连接 } } return res; }</span>
上文中,除了可以使用try catch 保证最后关闭连接。还有一种更简单的方法使用using 用于定义一个范围,在此范围的末尾将释放对象。
下面看变化的部分是写到哪里了呢?
首先定义数据库的连接字符串,这一点我们在运用学抽象工厂+反射的时候,已经应用到了。B/S 中也是一样的。真正的做法是在Web.config中添加配置语句,以后如果有更改直接更改这一个文本即可。
其次,具体的每个查询语句就直接写在了调用类里。
<span style="font-family:KaiTi_GB2312;font-size:18px;"> string sql = "insert into category(name) values(@caName)"; SqlParameter[] paras = new SqlParameter[]{ new SqlParameter("@caName",caName)};</span>
我们看大话设计模式的时候,也总是哪里代码复用多了,哪里就有了坏的味道。
放之四海而皆准,通过本文演示的sqlHelper的变化,我想总结这样一个思路,即常用的提炼出公共方法,并且里面涉及到的变化的东西只写类名,不具体。
所以只考虑三个问题:
一 :哪里重复
二:怎么抽象公共部分(全局变量?公共方法?还是其他)
三:变化的部分写在哪里
总结
前一阵写了自己的个人重构总结,今天 又看了看别人写的。感觉他们提到的收获,我也有。可是我应该总结的不到位,也总是把问题扩大化,才在机房结束之初,很挫败的感觉。吸取上次的教训,从今以后的东西不要怕难,多总结。联系旧知识。另外,之前实在不懂的要挂起来,就像SQLHelper。今后很多都会有恍然大悟的感觉,每一个阶段的学习,可以注意囫囵吞枣和盲人摸象,等待无结果所以不要纠结。大踏步,前方一定柳暗花明。