“三层架构”中的三层是指:表现层(UI)、业务逻辑层(BLL)、数据访问层(DAL)
表现层:通俗讲就是展现给用户的界面,即用户在使用一个系统时候他的所见所得。
位于最外层(最上层),离用户最近。用于显示数据和接收用户输入的数据,为用户提供一种交互式操作的界面。
业务逻辑层:针对具体问题的操作,也可以说是对数据层的操作,对数据业务逻辑处理。
负责处理用户输入的信息,或者是将这些信息发送给数据访问层进行保存,或者是调用数据访问层中的函数再次读出这些数据。中间业务层也可以包括一些对“商业逻辑”描述代码在里面
数据访问层:该层所做事务直接操作数据库,正对数据的增添、删除、修改、更新、查找。
仅实现对数据的保存和读取操作。数据访问,可以访问数据库系统、二进制文件、文本文档或是XML文档
优缺点:
优点:
1、开发人员可以只关注整个结构中的其中某一层;
2、可以很容易的用新的实现来替换原有层次的实现;
3、可以降低层与层之间的依赖;
4、有利于标准化;
5、利于各层逻辑的复用。
缺点:
1、降低了系统的性能。这是不言而喻的。如果不采用分层式结构,很多业务可以直接造访数据库,以此获取相应的数据,如今却必须通过中间层来完成。
2、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码。
简单的三层如下所示:
数据访问层:DAL
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类: 创建一个连接到数据库的类
{
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类:
{
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类(用于存储过程)
{
/// <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类:
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 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类:
/// 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表示层