三层架构浅析

    

“三层架构”中的三层是指:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)

表现层:通俗讲就是展现给用户的界面,即用户在使用一个系统时候他的所见所得。

位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。

 

业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。

负责处理用户输入的信息,或者是将这些信息发送给数据访问层进行保存,或者是调用数据访问层中的函数再次读出这些数据。中间业务层也可以包括一些对“商业逻辑”描述代码在里面

 

数据访问层:该层所做事务直接操作数据库,正对数据的增添、删除、修改、更新、查找。

仅实现对数据的保存和读取操作。数据访问,可以访问数据库系统、二进制文件、文本文档或是XML文档



优缺点:

    优点:

  1、开发人员可以只关注整个结构中的其中某一层;

  2、可以很容易的用新的实现来替换原有层次的实现;

  3、可以降低层与层之间的依赖;

  4、有利于标准化;

  5、利于各层逻辑的复用。

 

  缺点:

    1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。

  2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。

 

 

简单的三层如下所示:

数据访问层:DAL

sqlhelp类:

 
  
public class SqlHelp
{
private SqlConnection con; // 连接对象
private SqlCommand cmd; // 操作对象
private SqlDataAdapter sda; // 适配器(填充和更新数据库的一组数据命令和一个数据库连接)
private SqlDataReader reader; // 读取行
private DataSet ds; // 数据集

/// <summary>
/// 初始化连接对象
/// </summary>
public void Connection()
{
try
{
con
= new SqlConnection(SqlConn.Str);
con.Open();
}
catch (Exception)
{
///
}
}

public int Command( string strsql)
{
try
{
Connection();
// 打开连接
cmd = new SqlCommand(strsql, con);
int count = cmd.ExecuteNonQuery(); // 返回受影响的行数
return count;
}
catch (Exception)
{
return - 1 ;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 返回一个数据集合
/// </summary>
/// <param name="strsql"> 数据库操作语句 </param>
/// <returns> 数据集 </returns>
public DataSet ReturnDs( string strsql, string table)
{
try
{
Connection();
sda
= new SqlDataAdapter(strsql, con);
ds
= new DataSet();
sda.Fill(ds, table);
return ds;
}
catch (Exception)
{
return null ;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 返回一个只进的读取流
/// </summary>
/// <param name="strsql"> 数据库操作语句 </param>
/// <returns> 返回一行数据 </returns>
public SqlDataReader ReturnReader( string strsql)
{
try
{
Connection();
cmd
= new SqlCommand(strsql, con);
reader
= cmd.ExecuteReader();
return reader;
}
catch (Exception)
{
return null ;
}
finally
{
con.Dispose();
}
}
}

2.SqlConn类: 创建一个连接到数据库的类

 
  
public class SqlConn
{
private static string str = " server =.;database=Finance;uid=sa;pwd=123 " ;

/// <summary>
/// Sqlconn连接的属性Str
/// </summary>
public static string Str
{
get { return str; }
set { str = value; }
}
}

3.SqlAccess类:

 
  
namespace SQLAccessDatabase
{
class AccessDB
{
private string dbAddress;
private string sqlString;
private SqlConnection con = null ;

public AccessDB( string dbAddress, string sqlString)
{
this .dbAddress = dbAddress;
this .sqlString = sqlString;
}

/// <summary>
/// 连接数据库
/// </summary>
private void Connect()
{
try
{
if (con == null ) // 单件模式
con = new SqlConnection( this .dbAddress);
con.Open();
}
catch
{
}
}

/// <summary>
/// 对数据库进行操作
/// </summary>
/// <param name="strArray"> 字符串的参数 </param>
/// <returns> 是否连接成功 </returns>
public bool ConnectDB( params string [] strArray)
{
try
{
Connect();

SqlCommand cmd
= new SqlCommand( this .sqlString, con);

// 取SQL语句中的参数进行赋值
string [] sqlstr = this .sqlString.Split( ' @ ' );
int i = - 1 ;
string tempstr = "" ;
foreach ( string str in sqlstr)
{
i
++ ;
if (i == 0 )
continue ;
tempstr
= " @ " + str.Remove(str.IndexOf( ' ' ));
cmd.Parameters.Add(tempstr, SqlDbType.VarChar).Value
= strArray[i - 1 ];
}

// 对SQL语句进行操作
string s = sqlString.Remove(sqlString.IndexOf( ' ' ));
if (s == " select " )
{
SqlDataReader reader
= cmd.ExecuteReader();
if (reader.Read())
{
return true ;
}
}
else if (s == " insert " || s == " update " || s == " delete " )
{
int count = cmd.ExecuteNonQuery();
if (count >= 1 )
{
return true ;
}
}
return false ;
}
catch
{
return false ;
}
finally
{
con.Dispose();
}
}

/// <summary>
/// 无连接读取数据库
/// </summary>
/// <param name="tableName"> 获取表的名字 </param>
/// <returns> 数据集合 </returns>
public DataSet GetTable( params string [] tableName)
{
try
{
Connect();

SqlDataAdapter sda
= new SqlDataAdapter(sqlString, con);

DataSet ds
= new DataSet();
if (tableName.Length == 0 )
{
sda.Fill(ds);
}
else
{
foreach ( string str in tableName)
sda.Fill(ds, str);
}

return ds;
}
catch
{
return null ;
}
finally
{
con.Dispose();
}
}
}

public class SQLServer
{
public static string dbAddress = " server=.;database=Finance;uid=sa;pwd=123 " ;
}
}

4.DBHelper类(用于存储过程)

 
  
public class DBHelper
{
/// <summary>
/// 构建 SqlCommand 对象(用来返回一个结果集,而不是一个整数值)
/// </summary>
/// <param name="connection"> 数据库连接 </param>
/// <param name="storedProcName"> 存储过程名 </param>
/// <param name="parameters"> 存储过程参数 </param>
/// <returns> SqlCommand </returns>
private static SqlCommand BuildQueryCommand(SqlConnection connection, string storedProcName, IDataParameter[] parameters)
{
SqlCommand command
= new SqlCommand(storedProcName, connection);
command.CommandType
= CommandType.StoredProcedure;

foreach (SqlParameter parameter in parameters)
{
if (parameter != null )
{
// 检查未分配值的输出参数,将其分配以DBNull.Value.
if ((parameter.Direction == ParameterDirection.InputOutput || parameter.Direction == ParameterDirection.Input) &&
(parameter.Value
== null ))
{
parameter.Value
= DBNull.Value;
}
command.Parameters.Add(parameter);
}
}

return command;
}

/// <summary>
/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="storedProcName"> 存储过程名 </param>
/// <param name="parameters"> 存储过程参数 </param>
/// <returns> SqlDataReader </returns>
public static SqlDataReader RunProcedure( string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);
SqlDataReader returnReader;
connection.Open();
SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.StoredProcedure;
returnReader
= command.ExecuteReader(CommandBehavior.CloseConnection);
return returnReader;

}

/// <summary>
/// 执行存储过程,返回DataSet
/// </summary>
/// <param name="storedProcName"> 存储过程名 </param>
/// <param name="parameters"> 存储过程参数 </param>
/// <returns> SqlDataReader </returns>
public static DataSet RunProcedure( string storedProcName, IDataParameter[] parameters, string resultTableName)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);

SqlDataAdapter da
= new SqlDataAdapter( "" ,connection);

SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.StoredProcedure;

da.SelectCommand
= command;

DataSet ds
= new DataSet();

if (resultTableName.Trim() != "" )
da.Fill(ds, resultTableName.Trim());
else
da.Fill(ds);

return ds;

}

/// <summary>
/// 执行存储过程,返回SqlDataReader ( 注意:调用该方法后,一定要对SqlDataReader进行Close )
/// </summary>
/// <param name="storedProcName"> 存储过程名 </param>
/// <param name="parameters"> 存储过程参数 </param>
/// <returns> SqlDataReader </returns>
public static SqlDataReader RunSQL( string storedProcName, IDataParameter[] parameters)
{
SqlConnection connection
= new SqlConnection(Config.ConStr);
SqlDataReader returnReader;
connection.Open();
SqlCommand command
= BuildQueryCommand(connection, storedProcName, parameters);
command.CommandType
= CommandType.Text;
returnReader
= command.ExecuteReader(CommandBehavior.CloseConnection);
return returnReader;

}
}

 

业务逻辑层:BLL

Operation类:

 
  
#region 报销管理

SqlHelp help
= new SqlHelp();
public bool ExpendAccountPopedom()
{
string sqlstr = string .Format( " select * from Popedom_Employee inner join Popedom on Popedom_Employee.PopedomID=Popedom.PopedomID ,Employee where Popedom_Employee.EmployeeID={0} and PopedomName='{1}' and Employee.EmployeeID={2} and Grade like '{3}' " , int .Parse(IDNumber.IdNumber), " 报销管理 " , int .Parse(IDNumber.IdNumber), " %经理 " );
AccessDB adb
= new AccessDB(SQLServer.dbAddress, sqlstr);
return adb.ConnectDB();
}
public DataSet Bind( string table)
{
string strsql = " select *from ExpendAccount " ;
return RetrunnewDS(table, strsql);
}
// 将表中的数据在textBox一一显示
public DataSet ShowIntxt( string expendaccountid, string table)
{
string strsql = string .Format( " select *from ExpendAccount where ExpendaccountID={0} " , expendaccountid);
return RetrunnewDS(table, strsql);
}

// 提交报销申请
public bool ExpendAccount( int expendPeopleid, string goodTag, string purpose, string beforePay, string expendSum)
{
string strsql = string .Format( " insert into ExpendAccount (ExpendPeopleID,GoodsTag,ExpendaccountTime,GoodsPurpose,BeforePay,ExpendSum) values({0},'{1}','{2}','{3}','{4}','{5}') " , expendPeopleid, goodTag, DateTime.Now.ToShortDateString(), purpose, beforePay, expendSum);
return ReturnCount(strsql);
}
// 审批报销申请
public bool ExpendAccountExamin( string promiserstatu, string index)
{
string strsql = string .Format( " update ExpendAccount set PromiserStatu='{0}',Promiserid={1} where ExpendAccountId={2} " , promiserstatu, int .Parse(IDNumber.IdNumber), index);
return ReturnCount(strsql);
}
#endregion

#region 工资管理
// 将工资表中的数据一一读到txtBox中
public DataSet ShowIntxtPay( string table, string employeeid)
{
string strsql = string .Format( " select *from EmployeePay where EmployeeID={0} " , employeeid);
return RetrunnewDS(table, strsql);
}
// Bind显示工资表中数据
public DataSet BindPay( string table)
{
string strsql = " select *from EmployeePay " ;
return RetrunnewDS(table, strsql);
}
// 更新工资表
public bool EmployeePayUpdate( int id, string baspay, string perpay, string subsidy, string prize, string allpay, string perincome, string reallypay)
{
string strsql = string .Format
(
" update EmployeePay set EmployeeID={0},BasicPay='{1}',PerformancePay='{2}',Subsidy='{3}',Prize='{4}', AllPay ='{5}',PersonalIncometax='{6}',ReallyPay='{7}' where EmployeeID={0} " , id, baspay, perpay, subsidy, prize, allpay, perincome, reallypay, id);
return (ReturnCount(strsql));
}
// 添加员工工资信息
public bool EmployeePayAdd( int id, string baspay, string perpay, string subsidy, string prize, string allpay, string perincome, string reallypay)
{
string strsql = string .Format
(
" insert into EmployeePay ( EmployeeID,BasicPay,PerformancePay,Subsidy,Prize, AllPay,PersonalIncometax,ReallyPay ) values ({0},'{1}','{2}','{3}','{4}','{5}','{6}','{7}') " , id, baspay, perpay, subsidy, prize, allpay, perincome, reallypay);
return ReturnCount(strsql);
}
// 删除员工工资信息
public bool EmployeePayDel( int id)
{
string strsql = string .Format( " delete from EmployeePay where EmployeeID={0} " , id);
return ReturnCount(strsql);
}
#endregion

#region 方法
// 返回受影响行数
private bool ReturnCount( string strsql)
{
int count = help.Command(strsql);
if (count >= 1 )
{
return true ;
}
else
return false ;
}
// 返回数据集
private DataSet RetrunnewDS( string table, string strsql)
{
DataSet ds
= help.ReturnDs(strsql, table);
return ds;
}
#endregion

UserLogin类:防注入式攻击

 
  
public class UserLogin
{
public bool UseLogin( string name, string pwd)
{
string str = " server=.;database=Finance;uid=sa;pwd=123 " ;
using (SqlConnection con = new SqlConnection (str))
{
con.Open();
string strsql = " select * from PersonInfo where employeeid=@employeeid and employeepwd=@employeepwd " ;
SqlCommand cmd
= new SqlCommand(strsql, con);
cmd.Parameters.Add(
" @employeeid " ,SqlDbType.VarChar).Value = name;
cmd.Parameters.Add(
" @employeepwd " , SqlDbType.VarChar).Value = pwd;
SqlDataReader reader
= cmd.ExecuteReader();
if (reader.Read())
{
return true ;
}
else
return false ;
}
}

SqlHelp help
= new SqlHelp();
#region 方法
// 返回受影响行数
private bool ReturnCount( string strsql)
{
int count = help.Command(strsql);
if (count >= 1 )
{
return true ;
}
else
return false ;
}
// 返回数据集
private DataSet RetrunnewDS( string table, string strsql)
{
DataSet ds
= help.ReturnDs(strsql, table);
return ds;
}
#endregion
}

 

以上DAL仅仅是针对SqlServer数据库,要想针对所有的数据库均有效,可用到工厂模式。

下面是工厂模式封装的DAL针对多个数据库,而且既可以封装的SqlHelper不仅对简单的五大对象封装,而且还可以针对对存储过程的封装(就是将上面的DbHelper和SqlHelp结合起来用)

下面以PetShop4.0为例讲解如下:

DBUtility类:OracleHelper

 
  

/// <summary>
/// A helper class used to execute queries against an Oracle database
/// </summary>
public abstract class OracleHelper {

// Read the connection strings from the configuration file
public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings[ " OraConnString1 " ].ConnectionString;
public static readonly string ConnectionStringInventoryDistributedTransaction = ConfigurationManager.ConnectionStrings[ " OraConnString2 " ].ConnectionString;
public static readonly string ConnectionStringOrderDistributedTransaction = ConfigurationManager.ConnectionStrings[ " OraConnString3 " ].ConnectionString;
public static readonly string ConnectionStringProfile = ConfigurationManager.ConnectionStrings[ " OraProfileConnString " ].ConnectionString;
public static readonly string ConnectionStringMembership = ConfigurationManager.ConnectionStrings[ " OraMembershipConnString " ].ConnectionString;

// Create a hashtable for the parameter cached
private static Hashtable parmCache = Hashtable.Synchronized( new Hashtable());

/// <summary>
/// Execute a database query which does not include a select
/// </summary>
/// <param name="connString"> Connection string to database </param>
/// <param name="cmdType"> Command type either stored procedure or SQL </param>
/// <param name="cmdText"> Acutall SQL Command </param>
/// <param name="commandParameters"> Parameters to bind to the command </param>
/// <returns></returns>
public static int ExecuteNonQuery( string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
// Create a new Oracle command
OracleCommand cmd = new OracleCommand();

// Create a connection
using (OracleConnection connection = new OracleConnection(connectionString)) {

// Prepare the command
PrepareCommand(cmd, connection, null , cmdType, cmdText, commandParameters);

// Execute the command
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute an OracleCommand (that returns no resultset) against an existing database transaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="trans"> an existing database transaction </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> an array of OracleParamters used to execute the command </param>
/// <returns> an int representing the number of rows affected by the command </returns>
public static int ExecuteNonQuery(OracleTransaction trans, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute an OracleCommand (that returns no resultset) against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="conn"> an existing database connection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> an array of OracleParamters used to execute the command </param>
/// <returns> an int representing the number of rows affected by the command </returns>
public static int ExecuteNonQuery(OracleConnection connection, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {

OracleCommand cmd
= new OracleCommand();

PrepareCommand(cmd, connection,
null , cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a select query that will return a result set
/// </summary>
/// <param name="connString"> Connection string </param>
/// / <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> an array of OracleParamters used to execute the command </param>
/// <returns></returns>
public static OracleDataReader ExecuteReader( string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {

// Create the command and connection
OracleCommand cmd = new OracleCommand();
OracleConnection conn
= new OracleConnection(connectionString);

try {
// Prepare the command to execute
PrepareCommand(cmd, conn, null , cmdType, cmdText, commandParameters);

// Execute the query, stating that the connection should close when the resulting datareader has been read
OracleDataReader rdr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;

}
catch {

// If an error occurs close the connection as the reader will not be used and we expect it to close the connection
conn.Close();
throw ;
}
}

/// <summary>
/// Execute an OracleCommand that returns the first column of the first record against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="connectionString"> a valid connection string for a SqlConnection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> an array of OracleParamters used to execute the command </param>
/// <returns> An object that should be converted to the expected type using Convert.To{Type} </returns>
public static object ExecuteScalar( string connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();

using (OracleConnection conn = new OracleConnection(connectionString)) {
PrepareCommand(cmd, conn,
null , cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a OracleCommand (that returns a 1x1 resultset) against the specified SqlTransaction
/// using the provided parameters.
/// </summary>
/// <param name="transaction"> A valid SqlTransaction </param>
/// <param name="commandType"> The CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> The stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> An array of OracleParamters used to execute the command </param>
/// <returns> An object containing the value in the 1x1 resultset generated by the command </returns>
public static object ExecuteScalar(OracleTransaction transaction, CommandType commandType, string commandText, params OracleParameter[] commandParameters) {
if (transaction == null )
throw new ArgumentNullException( " transaction " );
if (transaction != null && transaction.Connection == null )
throw new ArgumentException( " The transaction was rollbacked or commited, please provide an open transaction. " , " transaction " );

// Create a command and prepare it for execution
OracleCommand cmd = new OracleCommand();

PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters);

// Execute the command & return the results
object retval = cmd.ExecuteScalar();

// Detach the SqlParameters from the command object, so they can be used again
cmd.Parameters.Clear();
return retval;
}

/// <summary>
/// Execute an OracleCommand that returns the first column of the first record against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(conn, CommandType.StoredProcedure, "PublishOrders", new OracleParameter(":prodid", 24));
/// </remarks>
/// <param name="conn"> an existing database connection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or PL/SQL command </param>
/// <param name="commandParameters"> an array of OracleParamters used to execute the command </param>
/// <returns> An object that should be converted to the expected type using Convert.To{Type} </returns>
public static object ExecuteScalar(OracleConnection connectionString, CommandType cmdType, string cmdText, params OracleParameter[] commandParameters) {
OracleCommand cmd
= new OracleCommand();

PrepareCommand(cmd, connectionString,
null , cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Add a set of parameters to the cached
/// </summary>
/// <param name="cacheKey"> Key value to look up the parameters </param>
/// <param name="commandParameters"> Actual parameters to cached </param>
public static void CacheParameters( string cacheKey, params OracleParameter[] commandParameters) {
parmCache[cacheKey]
= commandParameters;
}

/// <summary>
/// Fetch parameters from the cache
/// </summary>
/// <param name="cacheKey"> Key to look up the parameters </param>
/// <returns></returns>
public static OracleParameter[] GetCachedParameters( string cacheKey) {
OracleParameter[] cachedParms
= (OracleParameter[])parmCache[cacheKey];

if (cachedParms == null )
return null ;

// If the parameters are in the cache
OracleParameter[] clonedParms = new OracleParameter[cachedParms.Length];

// return a copy of the parameters
for ( int i = 0 , j = cachedParms.Length; i < j; i ++ )
clonedParms[i]
= (OracleParameter)((ICloneable)cachedParms[i]).Clone();

return clonedParms;
}

/// <summary>
/// Internal function to prepare a command for execution by the database
/// </summary>
/// <param name="cmd"> Existing command object </param>
/// <param name="conn"> Database connection object </param>
/// <param name="trans"> Optional transaction object </param>
/// <param name="cmdType"> Command type, e.g. stored procedure </param>
/// <param name="cmdText"> Command test </param>
/// <param name="commandParameters"> Parameters for the command </param>
private static void PrepareCommand(OracleCommand cmd, OracleConnection conn, OracleTransaction trans, CommandType cmdType, string cmdText, OracleParameter[] commandParameters) {

// Open the connection if required
if (conn.State != ConnectionState.Open)
conn.Open();

// Set up the command
cmd.Connection = conn;
cmd.CommandText
= cmdText;
cmd.CommandType
= cmdType;

// Bind it to the transaction if it exists
if (trans != null )
cmd.Transaction
= trans;

// Bind the parameters passed in
if (commandParameters != null ) {
foreach (OracleParameter parm in commandParameters)
cmd.Parameters.Add(parm);
}
}

/// <summary>
/// Converter to use boolean data type with Oracle
/// </summary>
/// <param name="value"> Value to convert </param>
/// <returns></returns>
public static string OraBit( bool value) {
if (value)
return " Y " ;
else
return " N " ;
}

/// <summary>
/// Converter to use boolean data type with Oracle
/// </summary>
/// <param name="value"> Value to convert </param>
/// <returns></returns>
public static bool OraBool( string value) {
if (value.Equals( " Y " ))
return true ;
else
return false ;
}
}

SqlHelper类:

 
  
/// <summary>
/// The SqlHelper class is intended to encapsulate high performance,
/// scalable best practices for common uses of SqlClient.
/// </summary>
public abstract class SqlHelper {

// Database connection strings
public static readonly string ConnectionStringLocalTransaction = ConfigurationManager.ConnectionStrings[ " SQLConnString1 " ].ConnectionString;
public static readonly string ConnectionStringInventoryDistributedTransaction = ConfigurationManager.ConnectionStrings[ " SQLConnString2 " ].ConnectionString;
public static readonly string ConnectionStringOrderDistributedTransaction = ConfigurationManager.ConnectionStrings[ " SQLConnString3 " ].ConnectionString;
public static readonly string ConnectionStringProfile = ConfigurationManager.ConnectionStrings[ " SQLProfileConnString " ].ConnectionString;

// Hashtable to store cached parameters
private static Hashtable parmCache = Hashtable.Synchronized( new Hashtable());

/// <summary>
/// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString"> a valid connection string for a SqlConnection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> an int representing the number of rows affected by the command </returns>
public static int ExecuteNonQuery( string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

using (SqlConnection conn = new SqlConnection(connectionString)) {
PrepareCommand(cmd, conn,
null , cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a SqlCommand (that returns no resultset) against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn"> an existing database connection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> an int representing the number of rows affected by the command </returns>
public static int ExecuteNonQuery(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

PrepareCommand(cmd, connection,
null , cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a SqlCommand (that returns no resultset) using an existing SQL Transaction
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="trans"> an existing sql transaction </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> an int representing the number of rows affected by the command </returns>
public static int ExecuteNonQuery(SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();
PrepareCommand(cmd, trans.Connection, trans, cmdType, cmdText, commandParameters);
int val = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// Execute a SqlCommand that returns a resultset against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// SqlDataReader r = ExecuteReader(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString"> a valid connection string for a SqlConnection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> A SqlDataReader containing the results </returns>
public static SqlDataReader ExecuteReader( string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();
SqlConnection conn
= new SqlConnection(connectionString);

// we use a try/catch here because if the method throws an exception we want to
// close the connection throw code, because no datareader will exist, hence the
// commandBehaviour.CloseConnection will not work
try {
PrepareCommand(cmd, conn,
null , cmdType, cmdText, commandParameters);
SqlDataReader rdr
= cmd.ExecuteReader(CommandBehavior.CloseConnection);
cmd.Parameters.Clear();
return rdr;
}
catch {
conn.Close();
throw ;
}
}

/// <summary>
/// Execute a SqlCommand that returns the first column of the first record against the database specified in the connection string
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="connectionString"> a valid connection string for a SqlConnection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> An object that should be converted to the expected type using Convert.To{Type} </returns>
public static object ExecuteScalar( string connectionString, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {
SqlCommand cmd
= new SqlCommand();

using (SqlConnection connection = new SqlConnection(connectionString)) {
PrepareCommand(cmd, connection,
null , cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}
}

/// <summary>
/// Execute a SqlCommand that returns the first column of the first record against an existing database connection
/// using the provided parameters.
/// </summary>
/// <remarks>
/// e.g.:
/// Object obj = ExecuteScalar(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24));
/// </remarks>
/// <param name="conn"> an existing database connection </param>
/// <param name="commandType"> the CommandType (stored procedure, text, etc.) </param>
/// <param name="commandText"> the stored procedure name or T-SQL command </param>
/// <param name="commandParameters"> an array of SqlParamters used to execute the command </param>
/// <returns> An object that should be converted to the expected type using Convert.To{Type} </returns>
public static object ExecuteScalar(SqlConnection connection, CommandType cmdType, string cmdText, params SqlParameter[] commandParameters) {

SqlCommand cmd
= new SqlCommand();

PrepareCommand(cmd, connection,
null , cmdType, cmdText, commandParameters);
object val = cmd.ExecuteScalar();
cmd.Parameters.Clear();
return val;
}

/// <summary>
/// add parameter array to the cache
/// </summary>
/// <param name="cacheKey"> Key to the parameter cache </param>
/// <param name="cmdParms"> an array of SqlParamters to be cached </param>
public static void CacheParameters( string cacheKey, params SqlParameter[] commandParameters) {
parmCache[cacheKey]
= commandParameters;
}

/// <summary>
/// Retrieve cached parameters
/// </summary>
/// <param name="cacheKey"> key used to lookup parameters </param>
/// <returns> Cached SqlParamters array </returns>
public static SqlParameter[] GetCachedParameters( string cacheKey) {
SqlParameter[] cachedParms
= (SqlParameter[])parmCache[cacheKey];

if (cachedParms == null )
return null ;

SqlParameter[] clonedParms
= new SqlParameter[cachedParms.Length];

for ( int i = 0 , j = cachedParms.Length; i < j; i ++ )
clonedParms[i]
= (SqlParameter)((ICloneable)cachedParms[i]).Clone();

return clonedParms;
}

/// <summary>
/// Prepare a command for execution
/// </summary>
/// <param name="cmd"> SqlCommand object </param>
/// <param name="conn"> SqlConnection object </param>
/// <param name="trans"> SqlTransaction object </param>
/// <param name="cmdType"> Cmd type e.g. stored procedure or text </param>
/// <param name="cmdText"> Command text, e.g. Select * from Products </param>
/// <param name="cmdParms"> SqlParameters to use in the command </param>
private static void PrepareCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, SqlParameter[] cmdParms) {

if (conn.State != ConnectionState.Open)
conn.Open();

cmd.Connection
= conn;
cmd.CommandText
= cmdText;

if (trans != null )
cmd.Transaction
= trans;

cmd.CommandType
= cmdType;

if (cmdParms != null ) {
foreach (SqlParameter parm in cmdParms)
cmd.Parameters.Add(parm);
}
}
}

 

 图片转自:http://www.cnblogs.com/terrydong/archive/2007/12/06/985722.html

背景:

由于目前服务的公司,系统复杂度很高,数据库使用了Oracle、SqlServer、MySql......(就差用到所有的数据库产品了,呵呵)

系统重构的过程中,之前写的基于sqlserver的简单三层架构已经不能满足系统重构的需求...

需求:

支持多类型数据库

操作多个同一类型数据库

参考:

PetShop4.0

解决方案框架图如上图

数据访问工具类

数据访问类使用DbProviderFactory实现,方法在父类实现,子类中只需通过实现CreateInstance()方法来指定providerName和connectionString 即可,唯一遗憾的是Mysql数据库不能通过这种方式实现,需要再单独写数据访问类了。

数据访问类 

 

 转载自:http://blog.sina.com.cn/s/blog_4a24068d01009mia.html

 工厂模式三层架构

项目

描述

BLL

商务逻辑层组件

DALFactory

用于定义要加载哪个数据库访问程序集的工厂类

IDAL

接口集合,需要被每一个DAL类具体实现

Model

业务实体模型

SQLServerDAL

SQL Server数据库的IDAL接口实现

Web

Web 页和用户控件

BLL:调用接口实现数据层的访问,至于调用的是哪个数据类的实现,由DALFactory来实现.

DALFactory:通过工厂模式来实现调用具体哪个的数据子层.通过读取读取web.config参数用反射机制来动态加载具体的程序集.

IDAL:接口是一种系列‘功能’的声明或名单,接口没有实现细节,只是一些功能方法的定义.

Model: 数据库是关系型,不是面向对象的,要实现面向对象那就得把平面的‘表’结合业务规则抽象成类.

SQLServerDAL:是接口层的(SQLServer)实现,为了支持多数据库还可以有OracleDAL的实现.具体使用哪个由DALFactory决定.

Common:项目所用的公共类库或组件。

DBUtility:对ADO.NET数据访问封装的组件类库。

 

简单三层结构

 

项目

描述

BLL

业务逻辑层

Common

通用类库组件

DAL

数据访问层

DBUtility

数据访问组件

Web

Web 页表示层

Model

业务实体模型

BLL:调用接口实现数据层的访问,至于调用的是哪个数据类的实现,由DALFactory来实现.

Common:项目所用的公共类库或组件。

DBUtility:对ADO.NET数据访问封装的组件类库。

Model: 数据库是关系型,不是面向对象的,要实现面向对象那就得把平面的‘表’结合业务规则抽象成类.

DAL:是接口层的(SQLServer)实现,为了支持多数据库还可以有OracleDAL的实现.具体使用哪个由DALFactory决定.

 

转载自:http://blog.csdn.net/xiaolukatie/archive/2009/04/01/4041109.aspx
工厂模式则是属于一种设计模式,指的是专门定义一个类来负责创建其他类的实例,属于类的创建型模式,通常根据一个条件(参数)来返回不同的类的实例。

以下是转自别人的观点,留待细看

设计模式也是分类的

三层模式是体系结构模式,MVC是设计模式

三层模式又可归于部署模式,MVC可归于表示模式,工厂模式可归于分布式系统模式。

三层模式跟工厂模式,个人的见解如下:

工厂当然是得建立在三层的基础上的

三层,简单的说,数据访问,业务逻辑,表示,3个层面,3层会在一定程度上降低效率

但是他的优点远远的大于了那一点点的缺点,代码易于维护,程序结构清晰,关键是松散耦合

工厂呢,就是

例如,如果我要个对象,就会让工厂去创建,创建完成,给你返回个结果。

假如你去吃麦当劳,你说要个汉堡,你不会自己去做吧,相当于,你跟服务员说,我要个汉堡,服务员跟后面的“工厂”说,然后工厂帮你做个汉堡,然后“工厂”会给你个结果

三层架构,数据层(DAL)、逻辑层(BLL)、表示层(UI);
从功能上来说:
表示层就象你去饭店吃饭,你点了一个清真鲈鱼。
业务层负责洗、切、蒸等。
数据层负责提供鱼、油、盐等。


确切的说现在应用一般为7层结构

---DBUtility数据层基类
---DALFactory数据层工厂类
---IDAL接口层
---SQLDAL接口实现层
---Model实体类
---Logic业务逻辑层
---Web表示层

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值