文章题目 | 文章作者 | 发表日期 | blog地址 |
设计自己的应用开发框架三(数据操作与业务实体) | 俞兆平 | 2007/11/29 | http://blog.csdn.net/dzfb/ |
如需转载请保留上述作者信息。
系列文章目录:
*设计自己的应用开发框架三(数据操作与业务实体)
设计自己的应用开发框架四(业务类库与业务逻辑)
设计自己的应用开发框架五(插件编写与用户界面)
设计自己的应用开发框架六(异常与日志)
设计自己的应用开发框架七(国际化)
设计自己的应用开发框架八(插件化)
通过前两篇文章您应该了解为什么需要自己的应用开发框架和该框架的整体结构了,从这一篇起,咱们就共同来探讨一下如何在自定义框架中设计我们的通用数据操作和规范业务实体了。无论你习惯将你的程序分为多少层来设计,但是这些都是细分经典的MVC模式。而这个数据操作与业务实体其实就相当于MVC中的Model。
对于业务实体的设计,有的人喜欢用XML进行描述,有的人喜欢用类。前者的灵活性很好,对于多变的业务逻辑来说,前者是个不错的方案。我选择后者,这样一来效率可以有一定的提高,设计上也更加简便一些。
我们通过一张图来概括的描述一下数据操作与业务实体的关系:
由上图我们可以看出,不同的业务实体拥有相同的父类,通过该父类,我们可以让所有的业务实体都具有最重要也是最基本的数据库连接、数据操作、以及性能优化等功能。各个业务实体直接又丝毫没有联系,这样一来当一个业务发生改变时完全不会影响到其它业务的运行,即便有联系有影响,那也是在业务逻辑中应该规定的内容,我们将在下一篇文章中来具体阐述这部分问题。
下面我们通过具体的数据操作基类和一个业务实体的程序片段来展示一下如何编写框架中的这部分代码。
数据基类:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace TFW.Base.BusinessEntity
... {
public class SqlBaseBE
...{
private static SqlConnection Connect;
/**//// <summary>
/// SQL命令文本
/// </summary>
protected string CommandText;
private DataTable ValueTable;
/**//// <summary>
/// 参数集合
/// </summary>
protected SqlParameter[] Parameters;
SqlBaseBE#region SqlBaseBE
public SqlBaseBE()
...{
Connect = new SqlConnection("MSSQL数据库连接字符串");
CommandText = "";
Parameters = null;
}
#endregion
LoadValueTable#region LoadValueTable
/**//// <summary>
/// 查询数据操作
/// </summary>
/// <returns>查询后的Table</returns>
protected DataTable LoadValueTable()
...{
try
...{
SqlDataAdapter da = new SqlDataAdapter(this.CommandText, Connect);
if (Parameters != null)
...{
da.SelectCommand.Parameters.AddRange(Parameters);
}
DataSet ds = new DataSet();
da.Fill(ds);
ValueTable = ds.Tables[0];
}
catch (SqlException ex)
...{
throw ex;
}
catch(Exception e)
...{
throw new Exception(e.Message + " 执行查询语句: " + this.CommandText + " 时出现错误! ");
}
finally
...{
Connect.Close();
}
return ValueTable;
}
#endregion
ExecuteNonQuery#region ExecuteNonQuery
/**//// <summary>
/// 执行ExecuteNonQuery
/// </summary>
/// <returns>影响的行数</returns>
protected int ExecuteNonQuery()
...{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Connect;
try
...{
Connect.Open();
cmd.CommandText = this.CommandText;
if (Parameters != null)
...{
cmd.Parameters.AddRange(Parameters);
}
return cmd.ExecuteNonQuery();
}
catch(SqlException ex)
...{
throw ex;
}
catch(Exception e)
...{
throw new Exception(e.Message + " 执行更新语句: " + this.CommandText + " 时出现错误! ");
}
finally
...{
Connect.Close();
}
}
#endregion
}
}
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;
namespace TFW.Base.BusinessEntity
... {
public class SqlBaseBE
...{
private static SqlConnection Connect;
/**//// <summary>
/// SQL命令文本
/// </summary>
protected string CommandText;
private DataTable ValueTable;
/**//// <summary>
/// 参数集合
/// </summary>
protected SqlParameter[] Parameters;
SqlBaseBE#region SqlBaseBE
public SqlBaseBE()
...{
Connect = new SqlConnection("MSSQL数据库连接字符串");
CommandText = "";
Parameters = null;
}
#endregion
LoadValueTable#region LoadValueTable
/**//// <summary>
/// 查询数据操作
/// </summary>
/// <returns>查询后的Table</returns>
protected DataTable LoadValueTable()
...{
try
...{
SqlDataAdapter da = new SqlDataAdapter(this.CommandText, Connect);
if (Parameters != null)
...{
da.SelectCommand.Parameters.AddRange(Parameters);
}
DataSet ds = new DataSet();
da.Fill(ds);
ValueTable = ds.Tables[0];
}
catch (SqlException ex)
...{
throw ex;
}
catch(Exception e)
...{
throw new Exception(e.Message + " 执行查询语句: " + this.CommandText + " 时出现错误! ");
}
finally
...{
Connect.Close();
}
return ValueTable;
}
#endregion
ExecuteNonQuery#region ExecuteNonQuery
/**//// <summary>
/// 执行ExecuteNonQuery
/// </summary>
/// <returns>影响的行数</returns>
protected int ExecuteNonQuery()
...{
SqlCommand cmd = new SqlCommand();
cmd.Connection = Connect;
try
...{
Connect.Open();
cmd.CommandText = this.CommandText;
if (Parameters != null)
...{
cmd.Parameters.AddRange(Parameters);
}
return cmd.ExecuteNonQuery();
}
catch(SqlException ex)
...{
throw ex;
}
catch(Exception e)
...{
throw new Exception(e.Message + " 执行更新语句: " + this.CommandText + " 时出现错误! ");
}
finally
...{
Connect.Close();
}
}
#endregion
}
}
我们在数据基类中提供了数据库连接方式、参数传递方式以及数据获得和数据执行,你还可以根据需要来扩充自己的数据基类,比如加入更多种类的数据库连接方式(我们这里只用MSSQL来做例子)和更好的数据连接性能方法(我们在这里使用了.NET提供的连接池,JAVA的程序员就要自己来写一个),加入存储过程的调用等等,这需要通过app.config/web.config来做更多的配置,在这里我想提醒大家,由于config文件是明文存在的,所以我们最好使用一些可逆的加密算法(如DES等)来转换这些节点,能大大提高系统的安全性。如果您想将这部分研究的更加透彻,参照petshop及duwamish将对您有所帮助。好,下面让我们再来看看数据实体的内容。
业务实体:
using
System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using TFW.Base.BusinessEntity;
using System.Data.SqlClient;
namespace T.AppBETest
... {
public class DeleteBE : TFW.Base.BusinessEntity.SqlBaseBE
...{
public DeleteBE()
...{
this.CommandText = @"delete from student where studentnumber = @studentnumber";
}
public int DelData(int x)
...{
SqlParameter[] para = new SqlParameter[1];
para[0] = new SqlParameter("@studentnumber", x);
para[0].SqlDbType = SqlDbType.Int;
this.Parameters = para;
return this.ExecuteNonQuery();
}
}
}
using System.Collections.Generic;
using System.Text;
using System.Data;
using TFW.Base.BusinessEntity;
using System.Data.SqlClient;
namespace T.AppBETest
... {
public class DeleteBE : TFW.Base.BusinessEntity.SqlBaseBE
...{
public DeleteBE()
...{
this.CommandText = @"delete from student where studentnumber = @studentnumber";
}
public int DelData(int x)
...{
SqlParameter[] para = new SqlParameter[1];
para[0] = new SqlParameter("@studentnumber", x);
para[0].SqlDbType = SqlDbType.Int;
this.Parameters = para;
return this.ExecuteNonQuery();
}
}
}
很明显,这是一个简单的数据库删除业务实体。对于业务实体的编写相对来说是简单的,因为它就是对目标系统的业务进行描述,只要你的SQL语句过关,那么在编写这部分内容的时候就不会有什么问题。不过,业务实体的编写并不是属于框架本身的范畴,它是在框架之外,作为目标系统底层的组成部分来编写的,这里给出范例是为了让您清楚的看到如何来利用数据基类为业务实体提供相关功能和规范。
多个业务实体在数据基类的帮助下,就能够方便的被业务逻辑层所控制,我们将在下一篇文章中来详细阐述这部分内容。