系统采用|B/S结构,共分三层,分别是数据访问层,业务规则层,Web外观层。它们各自有自己的职责,各自为政又互相配合从而形成一个软件的整体功能系统,数据访问层的职责是负责对数据源的存取(这里的数据源是指SQL Server 2000),业务规则层负责的是对数据按照业务流程的处理,Web外观层负责向用户提供交互的接口,只负责输入输出数据。这样设计是很普遍的,它提供了一个较好维护的体系。
设计:
1) 数据访问层:
很多人愿意在这一层封装大量的SQL脚本以简化上层的设计,但是这样的设计并不合适!业务一般情况下会有变化,如果把SQL脚本“硬编码”在一起,修改时不得不修改程序的源代码。而用户那里一般只有打包的二进制程序!所以较好的做法是将对数据的操作的脚本放在外面,一般是放在离数据近的地方,如SQL Server上,这里我们把它
编写成存储过程放在SQL Server服务器上。编写成存储过程有这样的两个好处:第一,业务改变时,只要改存储过程即可。第二,没有必要将大量的脚本通过网络传输到数据库服务器解析执行,给网络带来很大的负担。而是只是调用一个存储过程名而已,大大降低了网络负担和中间层的负担。 如:执行添加用户的操作
Create PROCEDURE dbo.User_Create
@RealName varchar(50),
@DeptName varchar(50),
@HashedPassWord varchar(50),
@Tel varchar(50),
@Address varchar(50),
@DutyName varchar(50),
@UserName varchar(50)
AS
begin tran
insert into [User] (UserName,RealName,DeptName,HashedPassWord,Tel,Address,DutyName) values(@UserName,@RealName,@DeptName,@HashedPassWord,@Tel,@Address,@DutyName)
if @@error!=0
begin
rollback
return 0
end
else
begin
commit
return 1
end
对于执行存储过程和维护和数据库连接状态的方法(如:ExecSQL(string SQL),Open())应当封装在一个公共类中共其他类使用,而不是每个类都有自己的数据库方法!这样的意图是可以减少重复依赖,而且如果将这个共享类的方法抽象出来成为一个接口,让所有用到他的类使用这个接口,在共享类发生变化时,使用它的类并不知晓这些变化,减少了依赖就意味着更好地适应变化!
如:
public class Database : IDisposable ,ISQLDataBase(参考于codePlus)
{
private SqlConnection con;
private DBConfig m_Config=DBConfig.Instance;
public int RunProc(string procName)
{
SqlCommand cmd = CreateCommand(procName, null);
cmd.ExecuteNonQuery();
this.Close();
return (int)cmd.Parameters["ReturnValue"].Value;
}
public int RunProc(string procName, SqlParameter[] prams)
{
SqlCommand cmd = CreateCommand(procName, prams);
cmd.ExecuteNonQuery();
this.Close();
return (int)cmd.Parameters["ReturnValue"].Value;
}
.......
}
接口:
public interface ISQLDataBase
{
int RunProc(string procName) ;
int RunProc(string procName, SqlParameter[] prams) ;
void RunProc(string procName, out SqlDataReader dataReader) ;
void RunCommand(string command,out SqlDataReader dataReader);
void RunProc(string procName, SqlParameter[] prams, out SqlDataReader dataReader) ;
SqlCommand CreateCommand(string procName, SqlParameter[] prams) ;
void Open();
void Close() ;
SqlParameter MakeInParam(string ParamName, SqlDbType DbType, int Size, object Value);
SqlParameter MakeOutParam(string ParamName, SqlDbType DbType, int Size);
SqlParameter MakeParam(string ParamName, SqlDbType DbType, Int32 Size, ParameterDirection Direction, object Value);
}
对于连接信息,如连接字符串不应在所有用到数据库的地方出现,负责在部署时不得不在所有的类中调整!所以把它方在XML配置文件中是明智的(分成集成和混合安全性),再用一个类管理它即可.
XML文件的内容:
<?xml version="1.0" standalone="yes" ?>
<NewDataSet>
<DBConfig>
<ServerName>Gaolei</ServerName>
<Machine>GAOLEI</Machine>
<DataBase>OA</DataBase>
</DBConfig>
<DBConfig>
<ServerName>Gaolei</ServerName>
<UID>sa</UID>
<PWD></PWD>
<Machine>Gaolei</Machine>
<DataBase>OA</DataBase>
</DBConfig>
<DBConfig>
<LogCount>100</LogCount>
</DBConfig>
</NewDataSet>。
对于数据实体层,它负责传递数据,是各层交换数据的地方。设计时应考虑这样几个因素:
第一:性能,交换数据的地方必须要